【问题标题】:Conditional sum using linq for Or condition使用 linq for Or 条件的条件求和
【发布时间】:2016-12-18 13:44:31
【问题描述】:

当我使用由OR 连接的两个条件时,SQL Server 的结果不正确。

我该如何解决?

这是我的 LINQ 代码并生成 SQL(为我创建的反射):

  query.Where(p => ((p.Code == "100000") Or p.Code.EndsWith("200")))
  query.Where(p => (p.year == "2015"))}

我在运行时添加了这个where 子句,现在我添加了另一个扩展方法,但它不起作用:

query.sum(p => p.value)

例外:

Microsoft.EntityFrameworkCore.dll 中出现“System.Data.SqlClient.SqlException”类型的异常,但未在用户代码中处理

附加信息:指定的非布尔类型的表达式 预期条件的上下文,靠近“AND”。

SQL 翻译:

SELECT SUM([e].[Value])
FROM [acc].[Data161] AS [e]
WHERE (CASE
          WHEN RIGHT([e].[Code], LEN(N'201')) = N'201'
             THEN CAST(1 AS BIT) ELSE CAST(0 AS BIT)
       END | 
       CASE
          WHEN RIGHT([e].[Code], LEN(N'199')) = N'199'
             THEN CAST(1 AS BIT) ELSE CAST(0 AS BIT)
       END) 
  AND ([e].[SetadCode] = N'161')

正确的 SQL 应该在AND 之前有= 1

但如果没有 sum 它可以正常工作,并在 SQL 命令中添加 = 1

【问题讨论】:

  • 发生错误是因为您有两个 WHERE。相反,我们将“与”或“或”放入您的第一个 WHERE。
  • 错误的 SQL 总是 是一个框架错误。请举报。
  • @jdweng 我在运行时在某些条件下添加了这个,这不是问题
  • @usr 我在 github 中添加了一个问题 :( 我希望我的代码是错误的,有人给我一个更好的方法。顺便说一下,我添加了一个问题
  • 你试过这个吗:query.Where(p => (p.year == "2015") And ((p.Code == "100000") 或者 p.Code.EndsWith(" 200")))

标签: c# sql-server linq entity-framework-core


【解决方案1】:

首先,Or 不是有效的 C# 运算符

.Where(p => ((p.Code == "100000") Or p.Code.EndsWith("200")))

如果您将其更改为 ||,则查询会正确转换并在没有问题的情况下执行。

查看生成的 SQL,我很确定您使用了按位或运算符 (|),在这种情况下,我得到了同样的错误。虽然这可能是 EF Core 翻译器错误,但无论如何您都不应该使用它 - 使用逻辑或 || 运算符,生成的 SQL 将不会包含所有 CASE WHEN 表达式,而是典型的简单 WHERE 条件。

【讨论】:

  • EF 用 Case When 翻译它,在向 linq 查询添加另一个条件后,它们都缺少“= 1”
  • 不,不是。在将其发布为答案之前,我已经检查了我写的所有内容。同样,请确保您使用的是|| 而不是|。还要检查您的 EF Core 版本。在 EF Core v.1.1.0 下测试和工作
  • 感谢您,我检查了 Ef 1.1.0,它与 Expression.OrElse() 配合得很好,非常感谢。你救了我,为什么我从来没想过? :)) 我刚刚看了你的回答,对不起。
  • 不客气。没问题,有时我们都很着急 :) 请小心使用 EF Core - 非常不稳定,每个小版本都可以改进一些东西,但也会破坏另一个。
【解决方案2】:

您可以使用|| 代替or

query.Where(p => ((p.Code == "100000") || p.Code.EndsWith("200")))

【讨论】:

    【解决方案3】:

    这对于评论来说太长了,但没有解决问题的 linq 部分。

    我希望where 子句看起来像这样:

    where (code = '100000' or p.code like '%200') and (p.year = '2015')
    

    所有产生的位操作都是不和谐的。注意上面的代码也是ANSI标准的SQL。

    【讨论】:

    • 我也是,但正如我所说,我使用反射并使用扩展方法添加条件,我的项目是一个大型报告项目,因此硬编码 where 子句以接近标准并不是一个好主意
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-05-30
    • 1970-01-01
    • 2011-04-12
    • 1970-01-01
    • 2016-02-15
    相关资源
    最近更新 更多