7

我正在尝试not in使用 NHLambdaExtensions 使用 NHibernate Criteria API 创建一个子句。阅读文档,我能够通过执行该in子句

.Add(SqlExpression.In<Zone>(z => zoneAlias.ZoneId, new int[] { 1008, 1010 }))

但是,当我把它包裹起来时,SqlExpression.Not我得到了错误

Error   5   The best overloaded method match for 'NHibernate.LambdaExtensions.SqlExpression.Not<oms_dal.Models.Zone>(System.Linq.Expressions.Expression<System.Func<oms_dal.Models.Zone,bool>>)' has some invalid arguments
Error   6   Argument '1': cannot convert from 'NHibernate.Criterion.ICriterion' to 'System.Linq.Expressions.Expression<System.Func<oms_dal.Models.Zone,bool>>'

我正在使用这段代码

.Add(SqlExpression.Not<Zone>(SqlExpression.In<Zone>(x => zoneAlias.ZoneId, new int[] { 1008, 1010 })))

我怎样才能做到这一点?使用常规的 Criteria API 我能够做到这一点

.Add(Restrictions.Not(Restrictions.In("z.ZoneId", new[] { 1008, 1010 })))
4

2 回答 2

2

使用带有 lambda 的旧世界似乎可行:

.Add(Expression.Not(SqlExpression.In<Zone>(z => zoneAlias.ZoneId, new int[] { 1008, 1010 }));
于 2010-12-23T11:48:37.597 回答
1

没有直接使用标准(我通常使用 Linq2NH),但看起来 Not 只是想要一个布尔 lambda,所以你不能给它另一个标准。这可能有效,尽管我看到 NH 在 lambdas 中的数组成员有问题:

.Add(SqlExpression.Not<Zone>(z=>new[]{1008,1010}.Contains(z.ZoneId))

编辑:废话。这里发生的事情是框架实际上并没有使用 lambda,所以虽然它编译,但框架在运行查询的过程中从未真正调用它。相反,它会反思性地检查您的委托的 MSIL,对您的 lambda 表达式进行逆向工程并将其转换为 SQL 命令的字符串。显然,这是一个相当复杂的过程,设计人员试图通过让您指定有关您正在做什么的提示(在本例中为您声明的 SqlExpression 的类型)并寻找模式来识别该过程来简化它。但是,在这种情况下,即使给出了提示,框架也不知道您要做什么。

如果评估 Not() 子句的翻译者无法判断逻辑循环或方法调用的目的,那么您很可能会被困在

.Add(SqlExpression.Not<Zone>(z=>z.ZoneId == 1008
                                || z.ZoneId == 1010))

天知道我必须以这种方式归结表达式才能使 Linq2NHibernate 正常工作。

于 2010-09-03T19:19:50.377 回答