Я использовал следующие методы для построения Order By Expression. Исходный источник
Это действительно пятно. Недостатком является то, что он работает только в том случае, если свойство строка.
Как я могу заставить его принимать разные типы свойств, не создавая кучу методов для разных типов данных?
public static bool PropertyExists<T>(string propertyName)
{
return typeof (T).GetProperty(propertyName, BindingFlags.IgnoreCase |
BindingFlags.Public | BindingFlags.Instance) != null;
}
public static Expression<Func<T, string>> GetPropertyExpression<T>(string propertyName)
{
if (typeof(T).GetProperty(propertyName, BindingFlags.IgnoreCase |
BindingFlags.Public | BindingFlags.Instance) == null)
{
return null;
}
var paramterExpression = Expression.Parameter(typeof(T));
return (Expression<Func<T, string>>)Expression.Lambda(
Expression.PropertyOrField(paramterExpression, propertyName), paramterExpression);
}
Использование
// orderBy can be either Name or City.
if (QueryHelper.PropertyExists<Club>(orderBy))
{
var orderByExpression = QueryHelper.GetPropertyExpression<Club>(orderBy);
clubQuery = clubQuery.OrderBy(orderByExpression);
}
else
{
clubQuery = clubQuery.OrderBy(c => c.Id);
}
Проблема
public class Club
{
public int Id { get; set; }
public string Name { get; set; }
public string City { get; set; }
public DateTime CreateDate { get; set; } <= this won't work
}
Мой текущий подход (слишком много операторов if)
public static Expression<Func<TSource, TKey>>
GetPropertyExpression<TSource, TKey>(string propertyName)
{
if (typeof (TSource).GetProperty(propertyName, BindingFlags.IgnoreCase |
BindingFlags.Public | BindingFlags.Instance) == null)
{
return null;
}
var paramterExpression = Expression.Parameter(typeof (TSource));
return (Expression<Func<TSource, TKey>>)
Expression.Lambda(Expression.PropertyOrField(
paramterExpression, propertyName), paramterExpression);
}
Недостатком является то, что в конце концов я получаю множество операторов if для каждого типа данных.
if (QueryHelper.PropertyExists<Club>(orderBy))
{
if(orderBy == "CreateDate")
{
var orderByExpression = GetPropertyExpression<Club, DateTime>(orderBy);
...
}
else if(orderBy == "Name" || orderBy == "City")
{
var orderByExpression = GetPropertyExpression<Club, string>(orderBy);
...
}
...
}
else
{
clubQuery = clubQuery.OrderBy(c => c.Id);
}