如何使用一个string通过expression式创buildEF顺序?
我试图实现这个转换
"Address.Street" => (p) => p.Address.Street "Name" => (p) => p.Name
我能够find一种方法来通过使用reflection的expression式来生成一个顺序,但是它不能用于像Address.Street
复杂sorting,因为它是针对单个属性级别的。
有没有办法做到这一点? 我已经看到,我编译的lambdaexpression式,但我不明白如何使它为这种情况下工作。
创build一个expression式并不困难,但棘手的部分是,如果不知道属性的types(因此select器expression式结果的types),如何将其绑定到相应的OrderBy(Descending)
/ ThenBy(Descendig)
方法, 。
以下是封装在自定义扩展方法中的所有内容:
public static partial class QueryableExtensions { public static IOrderedQueryable<T> OrderByMember<T>(this IQueryable<T> source, string memberPath) { return source.OrderByMemberUsing(memberPath, "OrderBy"); } public static IOrderedQueryable<T> OrderByMemberDescending<T>(this IQueryable<T> source, string memberPath) { return source.OrderByMemberUsing(memberPath, "OrderByDescending"); } public static IOrderedQueryable<T> ThenByMember<T>(this IOrderedQueryable<T> source, string memberPath) { return source.OrderByMemberUsing(memberPath, "ThenBy"); } public static IOrderedQueryable<T> ThenByMemberDescending<T>(this IOrderedQueryable<T> source, string memberPath) { return source.OrderByMemberUsing(memberPath, "ThenByDescending"); } private static IOrderedQueryable<T> OrderByMemberUsing<T>(this IQueryable<T> source, string memberPath, string method) { var parameter = Expression.Parameter(typeof(T), "item"); var member = memberPath.Split('.') .Aggregate((Expression)parameter, Expression.PropertyOrField); var keySelector = Expression.Lambda(member, parameter); var methodCall = Expression.Call( typeof(Queryable), method, new[] { parameter.Type, member.Type }, source.Expression, Expression.Quote(keySelector)); return (IOrderedQueryable<T>)source.Provider.CreateQuery(methodCall); }