2014-12-04 64 views
2

我目前正在對傳統的Web Forms Linq To SQL系統執行維護。用戶目前每天都會遇到不同的例外情況。主要的是「等待操作超時」,這表示長時間運行的查詢超載數據庫。有什麼方法可以跟蹤C#中IQueryable的執行嗎?

我有例外的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查詢。

回答

0
  1. 確保您的查詢不枚舉整個表格,然後過濾結果。因此,掃描您的代碼並確保您不會像例如singleordefault之類的過濾器之前調用ToList(),ToArray()等。

  2. 使用像這個免費的https://expressprofiler.codeplex.com/這樣的sql分析器來跟蹤你的查詢,你應該能夠找到長查詢和他們需要多長時間。

希望有所幫助。

+0

謝謝你的答案,但它並不真正適合我的問題。我已經說過,SQL分析器不是一個選項,因爲它不提供堆棧跟蹤。代碼太龐大,無法檢查每個頁面文件是否存在錯誤的linq;我已經檢查了常用的頁面,linq似乎沒問題。 – Callum 2014-12-10 09:24:46

+0

如果你只是在計時器之後,可以使用Stopwatch類,在調用查詢之前啓動它,並在通話結束後停止,然後您將知道您的查詢花了多少時間。但是您仍然可以通過檢查sql分析器來獲取somerhing,因爲它會告訴您到底執行了哪個查詢以及返回的查詢結果。 – 2014-12-10 09:51:22

相關問題