c# - EF 6 参数嗅探

标签 c# sql entity-framework

我有一个动态查询,它太大而无法放在这里。可以肯定地说,在当前形式中,它利用 CLR 过程根据传递的搜索参数的数量动态构建连接,然后获取该结果并将其连接到更详细的表,以带回对最终用户重要的属性。我已将整个查询转换为 LINQ to Entities,我发现它生成的 SQL 足够高效来完成这项工作,但是通过 EF 6 运行时,查询超时。获取生成的 SQL 并在 SSMS 中运行它只需 3 秒或更短的时间。我只能想象我的问题是参数嗅探。我已经尝试更新数据库中每个表的统计信息,但这并没有解决问题。

我的问题是:

我能否以某种方式通过 EF 嵌入诸如“OPTION RECOMPILE”之类的选项?

最佳答案

可以使用 EF6 的拦截功能在 DB 上执行之前操作其内部 SQL 命令,例如在命令末尾添加 option(recompile):

public class OptionRecompileHintDbCommandInterceptor : IDbCommandInterceptor
{
    public void NonQueryExecuting(DbCommand command, DbCommandInterceptionContext<Int32> interceptionContext)
    {
    }

    public void NonQueryExecuted(DbCommand command, DbCommandInterceptionContext<int> interceptionContext)
    {
    }

    public void ReaderExecuted(DbCommand command, DbCommandInterceptionContext<DbDataReader> interceptionContext)
    {
    }

    public void ReaderExecuting(DbCommand command, DbCommandInterceptionContext<DbDataReader> interceptionContext)
    {
        addQueryHint(command);
    }

    public void ScalarExecuted(DbCommand command, DbCommandInterceptionContext<object> interceptionContext)
    {
    }

    public void ScalarExecuting(DbCommand command, DbCommandInterceptionContext<object> interceptionContext)
    {
        addQueryHint(command);
    }

    private static void addQueryHint(IDbCommand command)
    {
        if (command.CommandType != CommandType.Text || !(command is SqlCommand))
            return;

        if (command.CommandText.StartsWith("select", StringComparison.OrdinalIgnoreCase) && !command.CommandText.Contains("option(recompile)"))
        {
            command.CommandText = command.CommandText + " option(recompile)";
        }
    }
}

要使用它,请在应用程序的开头添加以下行:

DbInterception.Add(new OptionRecompileHintDbCommandInterceptor());

关于c# - EF 6 参数嗅探,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25145667/

相关文章:

c# - 带有 It.IsAny 的 Expression<Func<T, bool>> 总是返回 true

C# MVC Razor Html.ValidationSummary 将消息显示为 HTML

C# 如何使用 HttpWebRequest 获取 JSON 字符串

sql - Oracle ProC INSERT INTO VALUES ( (选择 ...) )

c# - ASP.NET MVC 3 : why does it think my class is a complex type?

linq - linq 中的 .edmx 和 .dbml 文件有什么区别?

sql-server - 如何测试数据库是否托管在 SQL Azure 上?

c# - 我如何在winform中用位图替换光标

mysql - 在 MYSQL 中显示没有数据类型的列名

sql - Oracle 中的 View 和物化 View 有什么区别?