【发布时间】:2021-11-04 20:57:55
【问题描述】:
我正在编写一个扩展方法,它将属性名称作为字符串并构建一个表达式树以按该列排序。它需要支持 Linq-to-Entities,因为我希望在 SQL 中完成 order-by 操作。该方法目前按预期工作,但是我现在想优先考虑非空值,即无论顺序方向如何,始终将空值留在集合末尾。
这是我目前的方法:
public static IOrderedQueryable<T> OrderBy<T>(this IQueryable<T> source, string orderBy, bool ascending) {
Type type = typeof(T);
ParameterExpression parameter = Expression.Parameter(type, "p");
PropertyInfo property = type.GetProperty(orderBy);
if (property == null) {
throw new ArgumentException("The given value did not match any available properties.", nameof(orderBy));
}
// Get the property accessor p.SortColumn
Expression propertyAccess = Expression.MakeMemberAccess(parameter, property);
// Get the lambda expression p => p.SortColumn
LambdaExpression orderByExp = Expression.Lambda(propertyAccess, parameter);
// Call the OrderBy(Descending) method with the above lambda expression
MethodCallExpression resultExp = Expression.Call(typeof(Queryable),
ascending ? "OrderBy" : "OrderByDescending", new[] { type, property.PropertyType },
source.Expression, Expression.Quote(orderByExp));
return (IOrderedQueryable<T>)source.Provider.CreateQuery<T>(resultExp);
}
如果我不需要支持 Linq-to-Entities,我会这样写:
source.OrderBy(x => property.GetValue(x) == null).ThenBy/Descending(x => property.GetValue(x));
但是,Expression.Call()... 语法让我很困惑,因为我不完全了解幕后发生的事情。
如何将OrderBy(value == null) 操作添加到表达式树?
【问题讨论】:
标签: c# linq-to-entities expression-trees