<分区>
我使用以下方法构造Order By Expression。 Original Source
它真的很光滑。缺点是它仅在 Property 为 string 类型时才有效。
如何让它接受不同的属性类型而不为不同的数据类型创建一堆方法?
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);
}