【问题标题】:LINQ using conditional where generates wrong queryLINQ 使用条件 where 生成错误查询
【发布时间】:2020-10-24 06:44:53
【问题描述】:

对于 C# .NET Core 应用程序,我需要调整现有的 LINQ 语句以包含基于布尔属性的 WHERE 子句条件。最重要的是,我希望查询能够处理过滤,因此我不会将太多数据拉入应用程序。

这是 LINQ 语句的示例

var SalesPrice = 25;
var myQuery = from tl in db.TransactionLines
            where (
                tl.SalesPrice > SalesPrice &&
                tl.TemplateType != 'SomeType' &&
                tl.VoucherNumber == null
            )
            select tl;

这将产生以下干净简单的 SQL

SELECT *
FROM   [rbo].[TransactionLines] AS [tl]
WHERE  (([tl].[SalesPrice] > 25) 
AND    (([tl].[TemplateType] <> 'SomeType') OR [tl].[TemplateType] IS NULL)) 
AND    [tl].[VoucherNumber] IS NULL

如果我添加条件以根据属性更改 WHERE,则 LINQ 将如下所示

var SalesPrice = 25;
var SomeCondition = true;
var myQuery = from tl in db.TransactionLines
            where (
                tl.SalesPrice > SalesPrice &&
                tl.TemplateType != 'SomeType' &&
                SomeCondition ?
                    (tl.VoucherNumber == null) :
                    (tl.VoucherNumber != null || tl.VoucherNumber == null)
            )
            select tl;

这将生成以下不正确的查询

SELECT *
FROM [rbo].[TransactionLines] AS [tl]
WHERE CASE
    WHEN ([tl].[SalesPrice] > 25) AND (([tl].[TemplateType] <> 'SomeType') OR [tl].[TemplateType] IS NULL)
    THEN CASE
        WHEN [tl].[VoucherNumber] IS NULL
        THEN CAST(1 AS BIT) ELSE CAST(0 AS BIT)
    END ELSE CASE
        WHEN [tl].[VoucherNumber] IS NOT NULL OR [tl].[VoucherNumber] IS NULL
        THEN CAST(1 AS BIT) ELSE CAST(0 AS BIT)
    END
END = 1

因为当我执行此查询时,它将返回所有记录,而不是之前被 SalesPrice &gt; 25 过滤掉的那些记录。正确的方法是什么?或者有其他选择吗?

【问题讨论】:

  • 你有没有试过像tl.SalesPrice &gt; SalesPrice &amp;&amp; tl.TemplateType != 'SomeType' &amp;&amp; (SomeCondition ? (tl.VoucherNumber == null) : (tl.VoucherNumber != null || tl.VoucherNumber == null))这样放括号

标签: c# linq .net-core


【解决方案1】:

使用内联条件时要小心。好像忘了加括号 ( , ):

where (
    tl.SalesPrice > SalesPrice &&
    tl.TemplateType != 'SomeType' &&
    (SomeCondition ?
        (tl.VoucherNumber == null) :
        (tl.VoucherNumber != null || tl.VoucherNumber == null))
)

【讨论】:

  • 非常感谢...我盯着这段代码看了这么久,从来没有想到要添加括号。但是,我确实想知道为什么我需要小心。这有什么缺点吗?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-09-16
  • 2014-08-20
  • 2020-05-09
  • 2021-12-13
相关资源
最近更新 更多