我正在尝试动态创建表达式,该表达式将通过 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”时,不会引发异常。
所以我的问题:
我应该使用什么类型才能使其与任何可为 null 的属性一起使用?
是否可以使用一种类型并且适用于所有属性,无论这些属性可为空还是不可为空。
注意:我知道我可以使用 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/