2012-06-13 37 views
10

當外部庫包含一個LINQ提供程序,並且在執行動態表達式樹時引發異常時,如何在引發該表達式時中斷?如何在編譯的表達式樹中調試或設置break語句?

例如,我使用的是第三方LINQ2CRM提供商,這讓我打電話的IQueryableMax<TSource, TResult>()方法,但是當它拋出一個InvalidCastException,我無法在當異常被拋出當場斷裂,使其難以查看堆棧跟蹤,因爲當調試器在我的代碼中將其分解時它已經解開。我爲所提到的例外設置了「突破」。我調試設置爲:上哪兒我想打破

enter image description here


澄清。 I 不要想要打破LINQ表達式,但是我希望在執行表達式樹時斷開,或者換句話說,當IQueryable擴展方法Max()調用由LINQ提供程序提供的覆蓋時。堆棧跟蹤的頂部是這樣的,這是我想破內(或逐步執行,或其他):

at XrmLinq.QueryProviderBase.Execute[T](Expression expression) 
at System.Linq.Queryable.Max[TSource,TResult](IQueryable`1 source, Expression`1 selector) 
+0

你的意思是在這些方法中的一種堅持一個斷點在lambda表達式的一部分? –

+0

不知道是否[這有助於],但我現在正在進行搜索因爲這很有趣。所有的道路似乎都要去LinqPad。我看不出如何在沒有源代碼的情況下斷開它,然後當你有源代碼時,你能不能在負責'Max'的提供程序部分斷點? –

+0

[表達式樹](http://msdn.microsoft.com/en-us/library/bb397951.aspx)MSDN部分還有[調試表達式樹]一節(http://msdn.microsoft.com/ EN-US /庫/ ee725345)。我認爲這是我必須停止搜索並重新開始工作的地方;-) –

回答

4

我可能不理解的問題,而是實際上突破上線(似乎不可能),將表達式樹中的try-catch放入並記錄異常就足夠了嗎?

static void Main(string[] args) 
{ 
    var logExceptionMethod = typeof (Program).GetMethod("LogException", BindingFlags.Static | BindingFlags.NonPublic); 
    var createFileMethod = typeof (System.IO.File).GetMethod("Create", new[] {typeof(string)}); 

    // Parameter for the catch block 
    var exception = Expression.Parameter(typeof(Exception)); 

    var expression = 
     Expression.TryCatch(
     Expression.Block(typeof(void), 
      // Try to create an invalid file 
      Expression.Call(createFileMethod, Expression.Constant("abcd/\\"))), 

      // Log the exception from the catch     
      Expression.Catch(exception, Expression.Call(logExceptionMethod, exception))); 

    Expression.Lambda<Action>(expression).Compile()(); 
} 

static void LogException(Exception ex) 
{ 
    Console.WriteLine(ex.Message + "\r\n" + ex.StackTrace); 
} 

控制檯輸出:

The filename, directory name, or volume label syntax is incorrect. 

at System.IO.__Error.WinIOError(Int32 errorCode, String maybeFullPath) 
at System.IO.FileStream.Init(String path, FileMode mode, FileAccess access, Int32 rights, Boolean useRights, FileShare share, Int32 bufferSize, FileOptions options, SECURITY_ATTRIBUTES secAttrs, String msgPath, Boolean bFromProxy, Boolean useLongPath) 
at System.IO.FileStream..ctor(String path, FileMode mode, FileAccess access, FileShare share, Int32 bufferSize, FileOptions options) 
at System.IO.File.Create(String path) 
at lambda_method(Closure)