我目前正在对旧版Web窗体Linq To SQL系统执行维护。用户目前每天都会遇到不同的例外情况。主要是"等待操作超时"这表示长时间运行的查询重载数据库。
我有例外的elmah日志,但仅仅因为用户遇到错误并不意味着他们造成错误,所以对于Elmah我不能告诉那些查询是什么。
我尝试使用SQL Server Profiler来跟踪所有查询,但是它们太多了,并且它们没有提供堆栈跟踪,所以我无法找到它们的调用位置。
我的系统确实提供了DataContext的包装器,它看起来像这样:
public class DataAccess
{
public DataContext DataContext { get; set; }
public DataAccess(DataContext dataContext);
public IQueryable<T> SelectAll<T>();
public IQueryable<T> SelectAll<T>(Expression<Func<T, bool>> predicate);
public T SelectSingle<T>(Expression<Func<T, bool>> predicate);
public void DeleteItem<T>(T item);
public void UpdateItem<T>(T item);
public void AddItem<T>(T item);
public void AddItems<T>(IEnumerable<T> items);
}
DeleteItem
,UpdateItem
,AddItem
和SelectSingle
都会使用this.DataContext.SubmitChanges()
/ .FirstOrDefault()
在其方法中执行查询。 所以我提出了在这些方法中编写计时器的想法,以跟踪任何长时间运行的查询并使用完整的事件堆栈跟踪报告它们。
但是,由于读取量很大,系统中的大多数查询都将使用SelectAll
,这不会在DataAccess
中执行,因为在每个.aspx代码文件中都会调用此方法(其中有数百个)。在这些页面的每个页面中编程计时器是不可行的。
所以我的问题是:是否有任何方法可以在代码中计算所有可执行的Queryable,以便我可以使用StackTrace报告它,或者任何人都可以想出更好的方法来找出哪些代码包含不良的Linq查询。 / p>
答案 0 :(得分:0)
确保您的查询不会枚举整个表格,然后过滤结果。因此,扫描您的代码并确保在过滤器之前不要调用ToList(),ToArray()等,例如singleordefault。
使用像这个免费的https://expressprofiler.codeplex.com/这样的sql探查器来跟踪您的查询,您应该能够找到长查询以及它们需要多长时间。
希望有所帮助。