我有一个动态查询太大,无法放在这里。可以肯定地说,在其当前形式中,它利用 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());
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)