gpt4 book ai didi

c# - 为什么 EF 生成带有不必要的空值检查的 SQL 查询?

转载 作者:IT王子 更新时间:2023-10-29 03:54:04 26 4
gpt4 key购买 nike

我遇到了 EF 在搜索字符串字段时创建糟糕查询的问题。它以懒惰的程序员的风格生成了一个查询,以包含强制扫描整个索引的空检查。

考虑以下查询。

  1. 查询 1

    var p1 = "x";
    var r1 = ctx.Set<E>().FirstOrDefault(
    subject =>
    p1.Equals(subject.StringField));
  2. 查询 2

    const string p2 = "x";
    var r2 = ctx.Set<E>().FirstOrDefault(
    subject =>
    p2.Equals(subject.StringField));

查询 1 产生

WHERE (('x' = [Extent2].[StringField]) OR (('x' IS NULL) AND ([Extent2].[StringField] IS NULL))) 

并在 4 秒内执行

查询 2 产生

WHERE (N'x' = [Extent2].[StringField]) 

并在 2 毫秒内执行

有没有人知道任何解决方法? (没有参数不能是常量,因为它是由用户输入输入的,但不能为空。)

N.B 当分析时,这两个查询都是由 EF 使用 sp_executesql 准备的;作为原因,如果它们刚刚被执行,查询优化器将否定 OR 'x' IS NULL 检查。

for @Martin

最佳答案

设置 UseDatabaseNullSemantics = true;

  • UseDatabaseNullSemantics == true 时,(operand1 == operand2) 将被翻译为:

    WHERE operand1 = operand2
  • UseDatabaseNullSemantics == false 时,(operand1 == operand2) 将被翻译为:

    WHERE
    (
    (operand1 = operand2)
    AND
    (NOT (operand1 IS NULL OR operand2 IS NULL))
    )
    OR
    (
    (operand1 IS NULL)
    AND
    (operand2 IS NULL)
    )

This is documented by Microsoft :

Gets or sets a value indicating whether database null semantics are exhibited when comparing two operands, both of which are potentially nullable. The default value is false.

您可以在您的 DbContext 子类构造函数中设置它,如下所示:

public class MyContext : DbContext
{
public MyContext()
{
this.Configuration.UseDatabaseNullSemantics = true;
}
}

或者您也可以从外部将此设置设置为您的 dbContext 实例,就像下面的代码示例一样,从我的角度来看(请参阅@GertArnold 评论),这个方法会更好,因为它不会更改默认的数据库行为或配置):

myDbContext.Configuration.UseDatabaseNullSemantics = true;

关于c# - 为什么 EF 生成带有不必要的空值检查的 SQL 查询?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38433594/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com