如何使用linq表达式分割属性

3

假设我有一个实体:

MyEntity
{
...
Nullable<Int64> MyProperty
...
}

我希望能够做类似这样的事情:
Ctx.MyEntity.Where(x=>x.MyProperty/16 == 10) 

使用Linq.Expression

因此我创建了一个参数:

var param = Expression.parameter(typeOf(MyEntity));

那么,接下来是属性:

var prop = Expression.PropertyOrField(param,"MyProperty");

如果我想与 10 进行比较,我会这样做:

var cmp = Expression.equal(prop,Expression.constant(10,prop.Type));

但首先我需要将prop除以16。
于是我尝试:
var div = Expression.Divide(prop,Expression.constant(16, prop.type);

这会抛出一个不匹配类型的异常。

有人可以帮忙吗?

谢谢,


猜测:您需要访问该Nullable的.Value。也许编译器会在“类似于此”的代码中为您执行此操作。另一个想法是,在除法表达式创建中提供Int64类型(而不是Nullable!)。 - Amy B
1个回答

3

您需要创建类似于以下的除法表达式:

Expression.Divide(prop, Expression.Constant((Nullable<Int64>)16, prop.Type))

在将16作为属性的字面值使用时,需要明确将其转换为属性的类型,因为它的类型是Int32而不是与Nullable<Int64>相同。


你很棒!有件奇怪的事情是,如果我写Expression.Constant((Nullable<Int64>)16),它会创建一个类型为Int64的常量。你知道为什么吗? - Pit Ming
@Pit Ming Hm,这很有趣。我只能假设在像这样转换数字时,编译器(不太可能)或转换时进行了一些优化。但我不是很确定 - 也许可以为此创建一个单独的问题。 - Nikola Anusev
@PitMing,不存在常量可空(nullable)这样的东西。例如,你不能声明 const long? x = 16L;。为什么在传递可空值时不会出现类型错误?因为根本不存在所谓的装箱可空类型;当你将 Nullable<T> 装箱后,结果就是一个装箱后的 T。因此,在 Constant 方法中的逻辑无法区分你是否传递了 Nullable<Int64> 或普通的 Int64 - phoog
Lotar,接着我之前的评论,这个也可以:Expression.Divide(prop, Expression.Constant(16L, prop.Type)) - phoog

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接