我创建了很长的Linq-to-SQL表达式。您可能知道内部Linq-to-SQL使用exec sp_executesql
进行查询执行。当我在我的应用程序中运行它时 - 它以30秒的超时异常崩溃。
然后我将结果SQL从SQL Server Profiler复制到SQL Server Management Studio,将exec sp_executesql
替换为普通SELECT
并尝试调试它 - 它在4秒内执行。正如我看到它的执行计划更短更好。
然后我又回到了exec sp_executesql
,我发现执行计划又糟糕了。有任何想法吗?有没有解决方法?
更新:先生,我找到了原因。 exec sp_executesql
缓存错误的计划,然后永远使用它。当我向查询添加OPTION (RECOMPILE)
时,它会再次开始快速运行。但是我找不到如何将它添加到Linq-to-SQL查询中?
答案 0 :(得分:0)
强迫创建一个肮脏的黑客,但它起作用至少......
public static class XQueryableExt
{
public static IEnumerable<T> AsEnumerable<T>(
this IQueryable<T> source,
bool recompile)
{
if (!recompile)
return source.AsEnumerable<T>();
FieldInfo field =
source.GetType().GetField(
"context",
BindingFlags.NonPublic | BindingFlags.Instance);
if (field == null)
throw new ApplicationException("'field' is null");
DataContext dataContext = field.GetValue(source) as DataContext;
if (dataContext == null)
throw new ApplicationException("'dataContext' is null");
if (dataContext.Connection.State == ConnectionState.Closed)
dataContext.Connection.Open();
using (DbCommand command = dataContext.GetCommand(source)) {
command.CommandText += " OPTION (RECOMPILE)";
using (DbDataReader dataReader = command.ExecuteReader(CommandBehavior.CloseConnection)) {
return dataContext.Translate<T>(dataReader).ToArray();
}
}
}
}