c# - 动态 lambda 表达式 (OrderBy) 和可为 null 的属性类型

标签 c# linq entity-framework lambda expression-trees

我正在尝试动态创建表达式,该表达式将通过 Entity Framework 对数据库中的数据进行排序。但我遇到了一个问题,无法克服。也许让我解释一下我想要做什么。我的目标是创建这样的表达式:

x => x.Property

其中“Property”是我想要动态指定的属性的名称。

现在,让我们进入类,它代表数据库中的表(我简化了它以使事情更清楚):

public class MyModelClass
{
    public long MyLongProperty { get; set; }
    public decimal? MyNullableDecimalProperty { get; set; } // IMPORTANT: it's nullable
}

这是我的代码,我试图在其中创建前面描述的表达式:

// Db is EntityFramework context
IQueryable<MyModelClass> list = Db.MyModels.Select(x => x);

// x =>
var argument = Expression.Parameter(list.ElementType, "x");

// x.MyNullableDecimalProperty
var propertyToOrder = Expression.Property(argument, "MyNullableDecimalProperty");

// x => x.MyNullableDecimalProperty
var finalExpression = Expression.Call(
    typeof (Queryable),
    "OrderBy",
    new[] { list.ElementType, typeof(IComparable) },
    list.Expression,
    Expression.Lambda<Func<MyModelClass, IComparable>>(propertyToOrder, argument));

list = list.Provider.CreateQuery<MyModelClass>(finalExpression);

问题出现在第四条语句(var FinalExpression = Expression.Call(...))。我遇到异常:

Expression of type „System.Nullable`1[System.Decimal]” cannot be used for return type „System.IComparable”.

据我了解,问题在于我使用“IComparable”类型,其中“MyNullableDecimalProperty”为 Nullable,并且 Nullable 不使用 IComparable 接口(interface)。当我按“MyLongProperty”排序或替换“IComparable”时,不会引发异常。

所以我的问题:

  1. 我应该使用什么类型才能使其与任何可为 null 的属性一起使用?

  2. 是否可以使用一种类型并且适用于所有属性,无论这些属性可为空还是不可为空。

注意:我知道我可以使用 for ex。动态 Linq 库,但我对此解决方案不感兴趣 - 我想了解如何在不使用第 3 方库的情况下克服它。

最佳答案

没有理由使用IComparable。事实上,许多可比较的类型没有实现IComparable。只需使用您传递的任何内容的运行时类型即可:

var finalExpression = Expression.Call(
    typeof (Queryable),
    "OrderBy",
    new[] { list.ElementType, propertyToOrder.Type },
    list.Expression,
    Expression.Lambda(propertyToOrder, new [] { argument }));

关于c# - 动态 lambda 表达式 (OrderBy) 和可为 null 的属性类型,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32098485/

相关文章:

c# - 如何使用 Rx 定期执行代码直到第一次成功执行?

c# - 如何在 .NET 中创建表达式生成器

c# - LINQ - 根据条件过滤重复项

c# - 使用 LINQ 或 Entity Framework 拆分数据表以列出对象 C#

postgresql - 如何在 .net 核心上使用 ef 核心映射 postgresql 中的枚举(首先是数据库)

c# - 在身份中获取当前用户的电子邮件

登录/注册时的 C# ASP.Net 身份验证

c# - 检查列表是否包含多个指定值

c# - 多线程集差的有效方法

c# - 如何在 Entity Framework 中使用 join 使输出 Json 对象分级别 - 不是同一级别