【发布时间】:2019-06-09 13:21:12
【问题描述】:
我在 IQueryable 上创建了一个扩展,因为我想先按可空日期时间排序,然后仅使用属性字符串(即“activeTo”)按日期时间本身排序。我创建了以下代码:
public static IQueryable<T> Sort<T>(this IQueryable<T> source, string sortBy)
{
//create the expression tree that represents the generic parameter to the predicate
var param = Expression.Parameter(typeof(T), "p");
//create an expression tree that represents the expression p=>p.SortField.HasValue
var prop = Expression.Property(param, sortBy);
var target = Expression.Constant(null, prop.Type);
var bin = Expression.Equal(prop, Expression.Convert(target, prop.Type));
var exp = Expression.Lambda(bin, param);
string method = "OrderBy";
Type[] types = new Type[] { source.ElementType, exp.Body.Type };
var orderByCallExpression = Expression.Call(typeof(Queryable), method, types, source.Expression, exp);
//now do the ThenBy bit,sending in the above expression to the Expression.Call
exp = Expression.Lambda(prop, param);
types = new Type[] { source.ElementType, exp.Body.Type };
method = "ThenBy";
var ThenByCallExpression = Expression.Call(typeof(Queryable), method, types, orderByCallExpression, exp);
return source.Provider.CreateQuery<T>(ThenByCallExpression);
}
这个扩展被调用:
query.Sort("activeTo");
然后给出以下响应:
{
"title": "test 5",
"activeFrom": "2019-06-08T21:26:50.2833333",
"activeTo": "2019-06-08T21:26:50.2833333",
},
{
"title": "test 2",
"activeFrom": "2019-06-08T21:28:45.65",
"activeTo": null,
}
我希望 activeTo 为 null 的记录排在第一位,但事实并非如此。
有谁知道我做错了什么?
【问题讨论】:
-
您的代码构造表达式
OrderBy(p => p.activeTo == null)和true位于false之后,因为false通常由 0 表示,true由 1 表示。因此,您的表达式首先收集与null,然后所有值都为 null。但是,您的方法不应该生成像OrderBy(p => p.activeTo)这样的表达式,这似乎更适合像 Sort 这样的名称吗? -
@ckuri 是的,你说得对,我正在考虑创建另一个扩展程序,它可以按 null 排序,但我不确定该怎么做
-
我看到你实际上是在生成
OrderBy(p => p.activeTo == null).ThenBy(p => activeTo == null)。为什么?只需 OrderBy 就足够了。 -
@ckuri 我的错,这是一个错误。我想实际做 OrderBy(p => p.activeTo == null).ThenBy(p => activeTo)