2010-06-08 104 views
0

我正在使用LINQ和LINQKit在C#中編寫應用程序。我有一個非常大的數據庫表,裏面有公司註冊號。使用謂詞構建器的LinqKit堆棧溢出異常

我想要做一個LINQ查詢,它將產生等效的SQL: select * from table1 where'123','456''in'子句中可能有數千個術語。

首先我從國家等領域獲得公司註冊號碼。

我那麼所有的公司註冊號碼添加到謂詞:

 var predicate = PredicateExtensions.False<table2>(); 
     if (RegNos != null) 
     { 
      foreach (int searchTerm in RegNos) 
      { 
       int temp = searchTerm; 
       predicate = predicate.Or(ec => ec.regno.Equals(temp)); 
      } 
     } 

在Windows Vista專業版加4063項條款後堆棧溢出異常發生。在Windows Server 2003上添加了大約1000個術語後發生堆棧溢出異常。我不得不快速解決這個問題的演示。

爲了解決我用這個符號的問題:

 var predicate = PredicateExtensions.False<table2>(); 
     if (RegNos != null) 
     { 
      predicate = predicate.Or(ec => RegNos.Contains(ec.regno)); 
     } 

我的問題是:

  1. 爲什麼一個堆棧溢出發生使用foreach循環?

  2. 我認爲Windows Server 2003的每個進程\線程比NT \ 2000 \ XP \ Vista \ Windows 7工作站版本的Windows要小得多。

  3. 哪個是使用LINQ和LINQKit實現這個最快和最正確的方法?

有人建議我停止使用LINQ,回到動態SQL或ADO.NET,但我想使用LINQ和LINQKit是更好的可維護性。

回答

1

這裏有幾個問題。首先,封面下的L2S使用SQL UDF sp_execsql。 SQL UDF最多可以傳遞2100個參數,IIRC,常量和比較始終作爲參數發送。所以,即使表達式求值器沒有死亡,結果查詢也不會運行。表達式評估者可能因爲PredicateBuilder嵌套添加的表達式而死亡,並且L2S表達式評估者遞歸地遍歷表達式樹。也許你可以將大型過濾器列表填入臨時表並加入它?我相信設計師支持命名臨時表,或者您可以使用表值sproc插入過濾器值,然後使用L2S來完成繁重的工作。