我有一个模型课
public class MyModel
{
public long Id { get; set; }
public string Name { get; set; }
}
我当前正在从数据库中返回MyModel
的排序列表(按名称):
return await Db.MyModel
.AsNoTracking()
.OrderBy(x => x.Name)
但是,数据库中的值之一是“ N / A”,我希望通过一些选择器进行排序,最后保留“ N / A”,所以基本上:
return await Db.MyModel
.AsNoTracking()
.OrderBy(x => x.Name == "N/A)
.ThenBy(x => x.Name)
我创建了一个IQueryable
扩展名,但是在Expression.Call(...)
上出现了错误
InvalidOperationException:类型为'System.Linq.Queryable'的通用方法'OrderBy'与提供的类型实参和实参不兼容。如果方法是非泛型的,则不应该提供任何类型参数。
public static IQueryable<TSource> OrderNALast<TSource>(this IQueryable<TSource> source, Expression<Func<TSource, string>> selector)
{
var expression = source.Expression;
var parameter = Expression.Parameter(typeof(TSource), "x");
var left = (MemberExpression)selector.Body;
var right = Expression.Constant("N/A");
var predicateBody = Expression.Equal(left, right);
var lambda = Expression.Lambda<Func<TSource, bool>>(predicateBody, parameter);
expression = Expression.Call(
typeof(Queryable),
"OrderBy",
new[] { source.ElementType, left.Type },
expression,
lambda);
var appendedQuery = (IOrderedQueryable<TSource>)source.Provider.CreateQuery<TSource>(expression);
return appendedQuery.ThenBy(selector);
}
答案 0 :(得分:1)
哦,我想我知道了。
在Expression.Call中,第三个参数需要静态方法的通用类型参数来调用。
Queryable.OrderBy()
有两个重载:
public static System.Linq.IOrderedQueryable<TSource> OrderBy<TSource,TKey> (this System.Linq.IQueryable<TSource> source, System.Linq.Expressions.Expression<Func<TSource,TKey>> keySelector, System.Collections.Generic.IComparer<TKey> comparer);
和
public static System.Linq.IOrderedQueryable<TSource> OrderBy<TSource,TKey> (this System.Linq.IQueryable<TSource> source, System.Linq.Expressions.Expression<Func<TSource,TKey>> keySelector);
但不要给出
TSource
和bool
作为参数,您正在提供
TSource
和string
作为参数。
应该是:
expression = Expression.Call(
typeof(Queryable),
"OrderBy",
new[] { typeof(TSource), typeof(bool) },
expression,
lambda);
(或者您也可以将source.ElementType用作第一种类型。)