在检查BIT列时,LINQ生成了奇怪的SQL
本文关键字:SQL BIT 检查 列时 LINQ | 更新日期: 2023-09-27 17:58:18
我有以下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
不可为null。
Edit:我可能比优化器更聪明,但不幸的是,当使用Linq2Sql时,当"filter criteria"是一个参数时,就不会使用筛选的索引——这就是它的作用。所以最后我放弃了,转而使用存储过程。替代方案太恶心了。
注意:生成的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)
,这有点过头了!
是的,所以我想我已经想通了。以下线路
t1.IsPersonal == false
被优化为
!t1.IsPersonal
这反过来又被翻译成
(NOT ([t0].[IsPersonal] = 1))
似乎优化器应该"责怪"