【发布时间】:2016-01-20 17:19:32
【问题描述】:
我使用了以下方法来构造Order By Expression。 Original Source
真的很漂亮。缺点是它只有在属性是 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);
}
【问题讨论】:
-
所以问题出在
var orderByExpression = QueryHelper.GetPropertyExpression<Club>(orderBy);? -
问题是每种数据类型的重复代码太多。请参考我发布的最后一个代码。对于使用动态 OrderBy 的人来说,这似乎是一个非常普遍的问题;但我在 Google 中找不到任何解决方案。 我愿意接受任何建议或替代方法。
-
我不会传入“CreateDate”或“Name”或“City”之类的,而是传入某种表示要排序的属性的对象。该对象将能够生成排序表达式和其他有用的东西。更多代码,但没有凌乱的 if 丛林。
-
@MikeChristensen 返回的
Expression的类型是什么? -
@moarboilerplate - 嗯,我想
LambdaExpression?Expression<TDelegate>给你的唯一东西是Compile和Update他可能不需要。
标签: c# entity-framework