2017-01-06 14 views
3

我有2 LINQ查詢,一個返回我期望的,另一個不,我試圖理解爲什麼。我試圖找出Config中的所有節點是否有一個名爲「TEST」的節點,其Selected屬性爲True。這2個LINQ查詢有什麼區別?

查詢1 - 它返回正確的事情有內部的任何條件():

var res1 = 
(from config in _config.CurrentSettings.Config let name = config.name select config).Any(
    config => config.name.Equals("TEST") && config.selected == true); 

查詢2,它失敗了,有內選擇條件:

(_config.CurrentSettings.Config.Select(config => config.name.Equals("TEST") && config.selected)) 
.Any(); 
+1

'Select'返回'IEnumerable '您需要使用'Where'來過濾輸入序列。 – Lee

+0

'let name = config.name'在做什麼?其無用的 –

+1

任何返回bollean,選擇返回數據 –

回答

5

LINQ的Any()沒有條件意味着「至少有一行」。第一個查詢指定一個條件,使其「至少有一行匹配條件」。

要使第二個查詢等同於第一個查詢,請使用Any(flag => flag)或用Where替換Select。這兩個選項都比最初的Any差,因爲它們的內部條件不夠好,因爲它們不可讀。

1

這裏的整個事情是無用的。

(from config in _config.CurrentSettings.Config let name = config.name select config) 

您可以縮小它這個

_config.CurrentSettings.Config.Any(config => config.name.Equals("TEST") && config.selected == true); 

將執行與您的代碼第一個塊。

Select方法使用您給出的選擇器 將可枚舉轉換爲另一種形式。 無參數Any如果序列包含任何元素,則返回true。否則返回false。

1

您可能也想嘗試:

var isTestSelected = _config.CurrentSettings.Config.Any(config => config.name.Equals("TEST") && config.selected); 

查看的是SelectAny方法的文檔,可以提供一些見解。

如果你看看每這些鏈接的參數部分,你會看到,雖然這兩種方法接受一個Func,它們的使用實際上是不同的。

不限

謂詞 類型:System.Func<TSource, Boolean>甲函數來測試一個條件的每個 元件。

選擇

選擇 類型:System.Func<TSource, TResult>變換函數以便 應用到每個元件。

因此,在您查詢1例如,你申請轉換(或地圖),以每件商品的集合,它聲明一個局部變量的名稱 let name = config.name(未使用),然後就回報該對象原樣(沒有實際轉換任何東西)select config。這一點代碼是多餘的,可以刪除。

您的Any() lambda通過過濾與您的lambda謂詞不匹配的項目來完成Query1中的所有工作。

在Query2中,您將過濾lambda傳遞給轉換函數,然後使用不帶過濾器的過濾函數。

有很多不同的方法可以使用Linq獲得您想要的結果。我鼓勵你看看框架提供的不同映射(選擇器)和過濾(謂詞)功能(link)。