2010-09-03 60 views
7

我想用NHLambdaExtensions创建一个带有NHibernate Criteria API的not in子句。阅读文档,我能够做如何表达“不在”使用lambdas?

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

然而,当我把它包起来,以实现in条款各地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 }))) 

我该如何做到这一点?使用普通的标准API,我能够做到这一点

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

回答

1

与标准直接没有工作(我一般用Linq2NH),但看起来不只是想要一个布尔拉姆达,所以你不能给它另一个标准。这可能工作,虽然我已经看到新罕布什尔州与阵营成员在lambdas麻烦:

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

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

如果后面评估译者不()子句不能占卜逻辑回路或方法调用的目的,你可能会被套牢

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

有谁知道我不得不这种方式归结表达式Linq2NHibernate能够正常工作。

+0

正确的,它要一个布尔拉姆达。使用你的代码,NH现在说当我执行查询时,无法从new [] {1008,1010} .Contains(z.ZoneId)'确定成员类型。 – Mike 2010-09-03 19:28:26

+0

现在提供的新代码总是给出错误“无法确定来自...的成员”。我能想到的最简单和最丑陋的解决方案就是简单地执行'.Add(SqlExpression.Not(()=> zoneAlias.ZoneId == 1008))'。 – Mike 2010-09-07 16:18:13

2

使用旧世界与lambda表达式似乎工作:

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