2009-11-04 54 views
7

它看起來像我可以寫一個where x.a==1 && x.b==1作爲LINQ-to-SQL中多個where子句和&&運算符有什麼區別?

where x.a==1 
where x.b==1 

據我瞭解後者轉化成了.Where(x => x.a == 1).Where(x => x.b ==1),但這是如何轉化爲DB?在優化方面哪個更好?我總是可以從分析器中查看執行的查詢,但這不會是泛化,而更像是單一的經驗觀察,我不想依賴它。

使用帶反射器的System.Linq命名空間是另一種選擇,但這樣我們就錯過了將很多人花在同一件事上的機會。如果我沒有得到任何答案,我會做。

+2

幾乎重複http://stackoverflow.com/questions/1648730/when-using-linq-what-is-the-difference-between-and-multiple-where-clauses – 2009-11-04 11:27:20

+0

我沒有發現在我的搜索,但無論如何,這是LINQ到SQL的具體情況。 – 2009-11-04 11:34:23

+0

對LINQ到對象的影響將是顯而易見的,但LINQ到SQL尚不清楚。 – 2009-11-04 11:35:14

回答

7

好的,這是我的發現經過Reflector輸出一段時間後。 LINQ到對象使用WhereArrayIteratorWhereListIterator當它導致幾乎表現得像& &運營商結合起來,連續where謂詞,但不能作爲確切:

當您使用x.a==1 && x.b==1 where子句轉化爲Func<TSource, bool>看起來像這樣:

bool daspredicate(TSource x) 
{ 
    return x.a==1 && x.b==1 
} 

但是,當您使用連續的Where子句時,會有輕微的性能損失,至少源於非JITted IL-方面。下面是組合後代碼的樣子:

bool predicate1(TSource x) 
{ 
    return x.a==1; 
} 
bool predicate2(TSource x) 
{ 
    return x.b==1; 
} 
bool daspredicate(TSource x) 
{ 
    return predicate1(x) && predicate2(x); 
} 

正如您所看到的,這涉及到額外的函數調用開銷。除非JIT內聯函數,否則這可能相當昂貴。我相信它在這方面做得很好,但我們現在知道,如果我們自己結合我們的Where語句,JIT的工作變得更加容易,除非必要。

儘管在SQL的一面,查詢是相同的。即使在執行之前,調試器也會將查詢對象評估爲相同的SQL語句。 Linq名稱空間中我不能太過分,因爲事情似乎更復雜,但由於查詢是相同的,所以不應該像上面的LINQ到對象示例那樣受到懲罰。

編輯:我見過多個where語句導致SQL服務器上的嵌套子查詢的實例。我認爲,只要能夠保證安全,就堅持單個地方發言是更好的辦法。

2

這是由LINQ to SQL在這裏做正確的事情。我期望它將兩個「where」子句轉換爲一個SQL子句,兩個部分用「AND」連接起來。

嘗試這兩種 - 但我非常懷疑你會看到生成的SQL中的任何區別。

IMO你應該總是看看生成的SQL的任何非平凡的東西,但LINQ的工作方式肯定是鼓勵你通過小條款構建一個大的查詢 - 所以我真的期望它只是工作。

+0

它看起來像,謝謝! – 2009-11-08 14:53:01

2

DB側它們是相同的。這只是Linq-to-SQL可組合的一個副作用(即,您可以從一個查詢開始,然後添加其他條件,更改投影等)。

2

的代碼:

where x.a==1 
where x.b==1 

where x.a==1 && x.b==1 

爲C#反正語法糖。這將彙編爲

Where(...).Where(...) 

就像你猜它可能會一個LINQ方法鏈,讓我真的無疑有在生成的SQL任何區別。嘗試使用Jetbrains的Resharper工具 - 它甚至提供智能感知功能,可讓您選擇在兩者之間進行自動轉換,從而節省您重新編寫測試的時間。

我的首選是將非常簡單的查詢寫成方法鏈(例如,只有一個集合/表涉及並且沒有連接)以及更復雜的Linq Sugar語法。

+0

顯然他們不是很相同,請參閱我的答案。 – 2009-11-08 14:51:46

相關問題