我该如何表达“not in”?使用 lambda 表达式?

发布于 2024-09-17 06:34:08 字数 1033 浏览 3 评论 0原文

我正在尝试使用 NHLambdaExtensions 通过 NHibernate Criteria API 创建一个 not in 子句。阅读文档,我能够通过执行 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 })))

I'm trying to create a not in clause with the NHibernate Criteria API using NHLambdaExtensions. Reading the documentation I was able to implement the in clause by doing

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

However, when I wrap it around SqlExpression.Not I get the error

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>>'

I'm using this piece of code

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

How can I accomplish this? Using the regular Criteria API I was able to do this

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

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

鹿港巷口少年归 2024-09-24 06:34:08

将旧世界与 lambda 一起使用似乎可行:

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

Using the old world with the lambdas seems to work:

.Add(Expression.Not(SqlExpression.In<Zone>(z => zoneAlias.ZoneId, new int[] { 1008, 1010 }));
沙与沫 2024-09-24 06:34:08

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

.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 正常工作。

Haven't worked with criterion directly (I generally use Linq2NH), but it looks like Not simply wants a boolean lambda, so you can't give it another criterion. This may work, though I've seen NH have trouble with array members in lambdas:

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

EDIT: crap. What's going on here is that the framework is not actually using the lambda, so while this compiles, the framework never actually calls it in the process of running the query. It is instead reflectively examining the MSIL of your delegate, reverse-engineering your lambda expression and converting that to a string for the SQL command. That is, obviously, a rather complex process that the designers try to simplify by having you specify hints about what you're doing (in this case the type of SqlExpression you declared) and looking for patterns to identify the process. In this case, though, even given the hints, the framework has no clue what you're trying to do.

If the translator behind evaluating Not() clauses cannot divine the purpose of logic loops or method calls, you may well be stuck with

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

Goodness knows I've had to boil down expressions this way for Linq2NHibernate to work correctly.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文