2011-08-25 61 views
1

當一個創建LINQ查詢爲:替代爲凡LINQ語句生成ID。在(X,Y,Z)

var ids = new List<int> { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 }; 
var q = from r in context.Table 
     where ids.Contains(r.Id) 
     select r; 

與EF使用時,它產生的T-SQL類似於

SELECT ... FROM Table 
    WHERE Id IN (1, 2, 3, 4, 5, 6, 7, 8, 9, 10) 

一般來說,這是我所期望的,儘管它似乎搞亂了「查詢計劃編制」,因爲每個查詢都是不同的,因此需要在執行之前進行編譯。

由於EF否則在使用變量非常好((@p_ LINQ _)來避免這種情況,它不(默認)爲這些類型的查詢做到這一點。

是它在所有可能的爲了避免這種

表值參數映入腦海,但目前還不支持

BTW:?在現實生活中的查詢是一個複雜得多,並在IDS的項目數列表是很多,但仍然需要過濾掉數據,我們不想過濾'客戶端'

回答

0

我通過修改由EF生成的TSQL來實現這一次,以發出一個xml字符串參數,該參數在查詢本身中被評估爲表值參數。

這樣的影響並沒有我期望的那麼大,而且在某些領域的性能有了很大的提高,其他以前表現非常好的查詢現在表現非常糟糕。

最終,我們通過將自定義的Contains方法映射爲模型定義的函數(http://blogs.msdn.com/b/efdesign/archive/2009),最終將實現切換爲選擇加入方法/01/07/model-defined-functions.aspx)。所以用法就像

var ids = new List<int> { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 }; 
    var q = from r in context.Table 
    where CriteriaHelpers.Contains(ids, r.Id) 
    select r; 

並且這生成了類似下面的sql(它避免了每次查詢計劃重新編譯)。

SELECT ... FROM Table 
WHERE Id IN (SELECT Entity.ID.value('.', 'Id') AS ID FROM @parameterName.nodes('/items/i') AS Entity(ID)) 

這種方法也有大約2100參數限制得到的好處...

相關問題