2013-03-08 136 views
1

我喜歡將自己認爲與LINQ相當不錯,但我偶爾會嘗試完成某些我無法工作的東西。我想一個SPListItemCollection轉換成字典,以便我可以使用該密鑰來查找值,而不需要一個LINQ每次查詢:將for循環轉換爲linq查詢

var formsConfigItems = new Dictionary<string, string>(); 
foreach (SPListItem item in list.GetItems(query)) 
    formsConfigItems.Add(item.Title, (item["Value"] == null ? string.Empty : item["Value"].ToString())); 

這工作,但我希望做的一個更清潔的時尚,使用LINQ。 (沒什麼大不了的,但我喜歡使用LINQ在for循環只要有可能,雖然它的幕後同樣的事情

我試圖做這樣的事情:

var formsConfigItems = (from SPListItem i in list.GetItems(query) 
         select new { i.Title, i["Value"].ToString() }).ToDictionary<string, string>(k=>k.Key, k=>k.Value); 

但是,沒有按」不像是會工作,如果我嘗試使用上list.GetItems(query) lambda表達式,我不給使用.Where期權或任何LINQ命令(這是奇怪的,因爲它是一個SPListCollection

在此先感謝。

+0

「如果我嘗試使用上list.GetItems(查詢)lambda表達式,我不給選項使用「。返回類型是否實現IEnumerable ?如果不是,你需要調用list.GetItems(query).AsEnumerable()。 – 2013-03-08 14:58:49

回答

7

試試:

var formsConfigItems = list.GetItems(query) 
          .Cast<SPListItem>() 
          .ToDictionary(item => item.Title, 
             item => Convert.ToString(item["Value"])); 

要回答您的疑問:

如果我嘗試使用上list.GetItems lambda表達式(查詢),我給使用。凡或任何LINQ的選擇我不 命令(這是奇怪的 因爲它是一個SPListCollection)

這是因爲SPListCollection是一個「老派」的集合,實現IEnumerable但不IEnumerable<T>,所以C#/ LIN Q(無論如何在編譯時)無法知道它包含的項目的類型Cast<SPListItem>()調用幫助解決此問題 - 它將IEnumerable變成IEnumerable<T>,允許在編譯時解決類型代數問題。由於您明確指定了循環變量的類型,因此您的for循環沒有此問題 - 編譯器將爲您的序列中的每個項目插入一個強制轉換。

我試圖做這樣的事情(查詢表達式)。但那 似乎並沒有工作。

那是因爲你沒有正確構建匿名類型實例(屬性名稱不能推斷任意表達式)和你的Lambda表達式是不完全正確或者(您使用屬性名稱不匹配匿名類型的屬性名稱)。試試這個:

var formsConfigItems = (from SPListItem i in list.GetItems(query) 
         select new 
         { 
          i.Title, 
          Value = Convert.ToString(i["Value"]) 
         }).ToDictionary(a => a.Title, a => a.Value); 
+0

用你的編輯打敗我,大概24秒:) – 2013-03-08 15:09:03

+1

@Joe:乾杯,我贊成你的因爲額外的細節。 – Ani 2013-03-08 15:13:51

+0

謝謝大家。這非常有幫助 – 2013-03-08 16:21:41

2

阿尼的得到了更好的解決方案海事組織,但是你錯過了一兩件事:你的LINQ語句創建匿名項目的集合,但你不能在屬性名給予匿名課程。

k=>k.Key表達不起作用,因爲它不知道什麼Key是 - 你只定義Title(因爲你沒有給它一個名稱,它借鑑了對象中的一個)。 Value不能自動計算出來,所以會引發編譯器錯誤。

要做到這種方式,你需要特別聲明的名字:

new { Key = i.Title, Value = i["Value"].ToString() }