EF 6参数嗅探

妄想

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

我的问题是:

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

瓦希丁

在数据库上执行它们之前,可以使用EF6的拦截功能来操纵其内部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());

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章