【问题标题】:Dynamic linq OrderBy() failing after adding HasValue in the expression在表达式中添加 HasValue 后动态 linq OrderBy() 失败
【发布时间】: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&gt;=p.IsProcessStarted.HasValue)

【问题讨论】:

  • 请展示您尝试使用表达式树实现的 lambda order-by 表达式的示例。正如它所写的那样,表达式树似乎没有意义。
  • 这就是我的电话的样子。 var res = myQuery.OrderBy("IsProcessStarted", true) 而我要构建的表达式是 .OrderBy(p>=p.IsProcessStarted.HasValue)
  • 那我的回答是正确的。做出改变,然后尝试一下。但是,请考虑我的注释,以检查是否可以为空或在每种情况下都返回不同的表达式。

标签: .net entity-framework linq reflection expression


【解决方案1】:

您的代码正在尝试实现此OrderBy

.OrderBy(p => p.HasValue)

这个表达式返回一个bool。因此,要使其正常工作,您必须在 Expression.Call 调用中正确指定类型,如下所示:

MethodCallExpression resultExpression
    = Expression.Call(typeof(Queryable), command,
    new Type[] { type, typeof(bool) }, // Expression<Func<type, bool>>
    source.Expression,
    Expression.Quote(orderByExpression));

注意:我不知道这是否是您想要的,但如果您这样实现,代码可以正确编译和运行。但是,正如我在评论中所问的那样,您应该显示您想要实现的 lambda。您还应该修改代码以支持可空和不可空属性的场景。你正在检查这个,isNullable,但你没有在任何地方使用它

【讨论】:

  • 感谢 JotaBe,我正在尝试用我的表达式 OrderBy(p>=p.IsProcessStarted.HasValue) 来写这个。一旦我知道如何准备这个查询,我将使用 isNullable。我已经编辑了我的帖子以包含我要构建的表达式。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-04-17
  • 1970-01-01
相关资源
最近更新 更多