有没有办法跟踪C#中IQueryable的执行情况?

时间:2014-12-04 09:17:43

标签: c# asp.net linq-to-sql

我目前正在对旧版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);
}

DeleteItemUpdateItemAddItemSelectSingle都会使用this.DataContext.SubmitChanges() / .FirstOrDefault()在其方法中执行查询。 所以我提出了在这些方法中编写计时器的想法,以跟踪任何长时间运行的查询并使用完整的事件堆栈跟踪报告它们。

但是,由于读取量很大,系统中的大多数查询都将使用SelectAll,这不会在DataAccess中执行,因为在每个.aspx代码文件中都会调用此方法(其中有数百个)。在这些页面的每个页面中编程计时器是不可行的。

所以我的问题是:是否有任何方法可以在代码中计算所有可执行的Queryable,以便我可以使用StackTrace报告它,或者任何人都可以想出更好的方法来找出哪些代码包含不良的Linq查询。 / p>

1 个答案:

答案 0 :(得分:0)

  1. 确保您的查询不会枚举整个表格,然后过滤结果。因此,扫描您的代码并确保在过滤器之前不要调用ToList(),ToArray()等,例如singleordefault。

  2. 使用像这个免费的https://expressprofiler.codeplex.com/这样的sql探查器来跟踪您的查询,您应该能够找到长查询以及它们需要多长时间。

  3. 希望有所帮助。