我正在使用Cincura先生(http://blog.cincura.net/229310-sorting-in-iqueryable-using-string-as-column-name/)的这个伟大的通用排序助手来排序使用Entity Framework从SQL Server返回的记录
private static IOrderedQueryable<T> OrderingHelper<T>(IQueryable<T> source, string propertyName, bool descending, bool anotherLevel)
{
ParameterExpression param = Expression.Parameter(typeof(T), string.Empty); // I don't care about some naming
MemberExpression property = Expression.PropertyOrField(param, propertyName);
LambdaExpression sort = Expression.Lambda(property, param);
MethodCallExpression call = Expression.Call(
typeof(Queryable),
(!anotherLevel ? "OrderBy" : "ThenBy") + (descending ? "Descending" : string.Empty),
new[] { typeof(T), property.Type },
source.Expression,
Expression.Quote(sort));
return (IOrderedQueryable<T>)source.Provider.CreateQuery<T>(call);
}
问题是它可以从对象的任何属性起作用,但不能用于相关对象的属性。如果我有
public foo FOO;
public class foo
{
public string name {get;set};
public bar Bar {get;set;}
}
public class bar
{
public string name {get;set;}
}
我可以按 FOO.name 排序,但不能按 FOO.Bar.name 排序,但不能按foo.Bar.name排序。
我想我必须联系另一个表达,但到目前为止我的尝试都没有结果。我将不胜感激任何帮助。
答案 0 :(得分:1)
您必须自己构建嵌套成员表达式,例如,通过拆分propertyName-parameter并循环遍历它:
public static IOrderedQueryable<T> OrderingHelper<T>(IQueryable<T> source, string propertyName, bool descending, bool anotherLevel)
{
ParameterExpression param = Expression.Parameter(typeof(T), string.Empty); // I don't care about some naming
Expression body = param;
foreach (var member in propertyName.Split('.'))
{
body = Expression.PropertyOrField(body, member);
}
LambdaExpression sort = Expression.Lambda(body, param);
MethodCallExpression call = Expression.Call(
typeof(Queryable),
(!anotherLevel ? "OrderBy" : "ThenBy") + (descending ? "Descending" : string.Empty),
new[] { typeof(T), body.Type },
source.Expression,
Expression.Quote(sort));
return (IOrderedQueryable<T>)source.Provider.CreateQuery<T>(call);
}
答案 1 :(得分:0)
使酒吧具有可比性
public class bar : IComparable
{
public string name { get; set; }
public int CompareTo(object other)
{
return this.name.CompareTo(((bar)other).name);
}
}
答案 2 :(得分:0)
为了支持属性路径,请替换
行MemberExpression property = Expression.PropertyOrField(param, propertyName);
与
var property = propertyName.Split('.').Aggregate((Expression)param, Expression.PropertyOrField);