2012-01-17 22 views
6

我將我們的一些代碼從LINQ-to-SQL遷移到實體框架。以前,當運行在SQL Server的2100參數限制(描述爲here)時,我使用了由Marc Gravell here提供的解決方案。正如他自己的迴應所述,它不適用於實體框架。實體框架擊中2100參數限制

我完全不熟悉表達式以知道從哪裏開始,但我所尋找的基本上是相同的擴展方法,但適用於實體框架。預先感謝您提供的任何幫助。

+1

創建查詢需要超過2100個IN語句的靜態定義項(這是'Contains'的計數器部分)看起來不是一個正確的方法。這種操作應該在數據庫上完全處理,而不需要從客戶端傳遞數據。 – 2012-01-17 17:18:58

+0

我瞭解您的擔憂,但肯定會有所有*所需數據不在數據庫中的情況。確實有傳遞如此龐大的參數列表的替代方案,但是這個簡單的方法在我們如何使用它的過程中非常靈活(並且有99%的時間不需要使用它)。 – Ocelot20 2012-01-17 17:32:35

回答

13

EF中不存在2100參數限制問題。我在the AdventureWorks database上運行測試(在SQL Express 2008 R2中):我試圖獲得所有ProductCategoryId位於值範圍(1,2,3)的產品。

使用LINQ,生成的SQL WHERE條款如下:

WHERE [t0].[ProductCategoryID] IN (@p0, @p1, @p2) 
-- @p0: Input Int (Size = -1; Prec = 0; Scale = 0) [1] 
-- @p1: Input Int (Size = -1; Prec = 0; Scale = 0) [2] 
-- @p2: Input Int (Size = -1; Prec = 0; Scale = 0) [3] 

(這會導致最大參數號問題),而與EF 4.0它看起來像這樣:

WHERE [Extent1].[ProductCategoryID] IN (1,2,3) 

接下來,我已經用EF對3000個值進行了測試:

var categoryList = Enumerable.Range(1, 3000).Select(i => (int?)i).ToArray(); 

using (var aw = new AdventureWorksEntities()) 
{ 
    var products = aw.Products 
     .Where(p => categoryList.Contains(p.ProductCategoryID)) 
     .ToList(); 
} 

While這是非常低效的,它工作併產生預期的結果。

然而,也可以使用InRange擴展provided by Marc Gravell與EF,通過也使用LINQKit library,像這樣:

using (var aw = new AdventureWorksEntities()) 
{ 
    var products = aw.Products 
     .AsExpandable() 
     .InRange(p => p.ProductCategoryID, 1000, categoryList) 
     .ToList(); 
} 

(該AsExpandable擴展是在LINQKit定義)

這產生預期結果(以塊的形式執行查詢)以及取決於列表中項目的數量和塊的大小,可能比非分塊解決方案有效得多。