2012-02-04 65 views
1
以下兩個查詢之間的不同

我不明白哪個查詢應該使用下面的查詢和之間在什麼條件下的差異:什麼是LINQ

var productGroups = 
     from p in products 
     group p by p.Category into g 
     where g.Any(p => p.UnitsInStock == 0) 
     select new { Category = g.Key, Products = g }; 



var productGroups = 
     from p in products 
     group p by p.Category into g 
     where g.Where(p => p.UnitsInStock == 0) 
     select new { Category = g.Key, Products = g }; 
+1

當你嘗試運行它們時會發生什麼? – 2012-02-04 05:04:23

+0

他們都給出了期望的結果,但我不明白他們兩個的可用性 – 2012-02-04 05:10:48

+1

@DewasishMitruka,第二* *不可能*給出所需的結果。所提供的代碼是非法的。 – 2012-02-04 05:11:18

回答

4

不同的是,第二是不合法的代碼和不會編譯。

where g.Where(...) 

g.Where本身就是一個過濾操作。它產生一系列無論什麼類型g碰巧是。它確實是而不是產生一個布爾值,這是在另一個where表達式中用作謂詞的必要條件。

另一方面,g.Any(...)是一種返回布爾值的方法,它允許您在查詢的where子句中使用它。

第一個查詢(合法的)按類別對您的產品進行分組,然後過濾以選擇具有庫存爲0個單位的產品的組。只要該類別中的任何產品中有0個庫存單位,就將該組選擇爲包含該類別的匿名類型,然後選擇該類別中的產品。

如果你有

var products = new List<Product> 
{ 
    new Product { Category = "Widgets", Name = "Foo", UnitsInStock = 14 }, 
    new Product { Category = "Widgets", Name = "Bar", UnitsInStock = 0 }, 
    new Product { Category = "Frobbers", Name = "Baz", UnitsInStock = 32 }, 
    new Product { Category = "Frobbers", Name = "Blah", UnitsInStock = 9 } 
}; 

然後小工具將通過您的謂詞,因爲它有0個單位的產物。 Frobbers將被過濾掉。

通過在Where之後應用Any方法,可以固定第二個查詢以執行與第一個查詢相同的功能。

where g.Where(p => p.UnitsInStock == 0).Any() 

因此,在輸出中,因爲謂詞相同,所以沒有區別。區別在於謂詞被指定的地方。在第一個查詢中,它使用接受謂詞的Any的重載,第二個(一旦修正)使用無謂詞的重載,但在通過Where方法應用了謂詞之後。兩種方法都是通過這些方法懶散地流動元素,爲了驗證條件,只對必要的進行評估。因此,它主要取決於你使用哪個版本,並且我會簡單地選擇接受謂詞的版本Any