【发布时间】:2015-12-16 19:26:20
【问题描述】:
我遵循this link 使用表达式树在 linq 查询中创建动态 orderby 子句。
但后来我遇到了一个场景,我必须对列的值进行排序,同时牢记 null 值,因为我的数据库列允许 null 即所有非空值应按升序排序,然后应遵循空值。
所以我跟着this link 修改我的动态LINQ 代码来处理上述情况。即我试图在我的OrderBy() 电话中添加HasValue 电话。但它开始失败并出现以下错误。
类型“System.Linq.Queryable”上没有通用方法“OrderBy”与提供的类型参数和参数兼容。如果方法是非泛型的,则不应提供类型参数。
导致Expression.Call() 失败的参数:
p.IsProcessStarted.HasValue
下面是我正在使用的代码:
public static class ExtensionMethods
{
public static IQueryable<TEntity> OrderBy<TEntity>(
this IQueryable<TEntity> source, string orderByProperty, bool desc)
{
string command = desc ? "OrderByDescending" : "OrderBy";
var type = typeof(TEntity);
var property = type.GetProperty(orderByProperty);
var propertyType = property.PropertyType;
bool isNullable = propertyType.IsGenericType
&& propertyType.GetGenericTypeDefinition() == typeof(Nullable<>);
var parameter
= Expression.Parameter(type, "p");
MemberExpression propertyAccess
= Expression.MakeMemberAccess(parameter, property);
MemberExpression hasValue
= Expression.Property(propertyAccess, "HasValue");
LambdaExpression orderByExpression
= Expression.Lambda(hasValue, parameter);
MethodCallExpression resultExpression
= Expression.Call(typeof(Queryable), command,
new Type[] { type, property.PropertyType }, source.Expression,
Expression.Quote(orderByExpression));
return source.Provider.CreateQuery<TEntity>(resultExpression);
}
}
这就是我调用上述扩展方法的方式:
var res = myQuery.OrderBy("IsProcessStarted", true)
而我要构建的表达式是.OrderBy(p>=p.IsProcessStarted.HasValue)
【问题讨论】:
-
请展示您尝试使用表达式树实现的 lambda order-by 表达式的示例。正如它所写的那样,表达式树似乎没有意义。
-
这就是我的电话的样子。 var res = myQuery.OrderBy("IsProcessStarted", true) 而我要构建的表达式是 .OrderBy(p>=p.IsProcessStarted.HasValue)
-
那我的回答是正确的。做出改变,然后尝试一下。但是,请考虑我的注释,以检查是否可以为空或在每种情况下都返回不同的表达式。
标签: .net entity-framework linq reflection expression