检查BIT列时从LINQ生成的奇怪SQL
我有以下LINQtoSQL语句
from t1 in __table1 join t2 in __table2 on t1.Id equals t2.OtherTableId where t2.BranchId == branchId && !t1.IsPersonal select t1.Id
这会生成以下SQL
SELECT DISTINCT [t0].[Id] FROM [__table1] AS [t0] INNER JOIN [__table2] AS [t1] ON [t0].[Id] = [t1].[OtherTableId] WHERE ([t1].[BranchId] = @p0) AND (NOT ([t0].[IsPersonal] = 1))
现在我的问题是:
(NOT ([t0].[IsPersonal] = 1))
我怎么能写LINQ来说
[t0].[IsPersonal] = 0
注意: IsPersonal
不可为空。
是的,所以我认为我已经弄明白了。 以下行
t1.IsPersonal == false
得到优化
!t1.IsPersonal
反过来,这直接翻译成了
(NOT ([t0].[IsPersonal] = 1))
似乎优化者是“责备”
编辑:我可能已经超越了优化器但不幸的是,当使用Linq2Sql时,当’过滤条件’是参数时,不使用过滤的索引 – 这就是它的作用。 所以最后我放弃了并切换到存储过程。 替代品太蹩脚了。
注意:生成的SQL 确实可以使用没有索引提示的筛选索引,但由于我在SSMS中运行,因此查询计划缓存不适用。
啊哈! 终于设法超越了优化器。
WHERE object.Equals(t.Voided, 0)
或
WHERE object.Equals(t.Voided, "false")
哪个产生
WHERE ([t0].[Voided] = @p0)
@p0
作为字符串或数字发送,SQL Server为您转换为布尔值。
这似乎适用于过滤索引(和强制提示),这是我首先需要绕过优化器的原因。
注意:由于某种原因,有时"0"
给出一个布尔解析错误,所以0
或"false"
可能更好。 可能取决于您的查询的一些细微之处。
我更喜欢0
因为"false"
最终成为varchar(8000)
,这有点矫枉过正!