2010-04-28 97 views
2

目前我得到HeaderColumns列表從下面的XML片段:LINQ to XML - 如何從匿名對象獲取字典?

<PerformancePanel> 
    <HeaderColumns> 
    <column performanceId="12" text="Over last month %" /> 
    <column performanceId="13" text="Over last 3 months %" /> 
    <column performanceId="16" text="1 Year %" /> 
    <column performanceId="18" text="3 Years % p.a." /> 
    <column performanceId="20" text="5 Years % p.a." /> 
    <column performanceId="22" text="10 Years % p.a." /> 
    </HeaderColumns> 
</PerformancePanel> 

從我創建一個對象如下:(!admitedly類似於前面一個問題)

var performancePanels = new 
{ 
    Panels = (from panel in doc.Elements("PerformancePanel") 
      select new 
      { 
       HeaderColumns = (from column in panel.Elements("HeaderColumns").Elements("column") 
           select new 
           { 
            PerformanceId = (int)column.Attribute("performanceId"), 
            Text = (string)column.Attribute("text") 
           }).ToList(), 
       }).ToList() 
}; 

我倒是一樣,如果HeaderColumns是一個字典(),因此以後我提取從匿名對象中的值等如下:

Dictionary<int, string> myHeaders = new Dictionary<int, string>(); 
foreach (var column in performancePanels.Panels[0].HeaderColumns) 
{ 
    myHeaders.Add(column.PerformanceId, column.Text); 
} 

以爲可以的政績與LINQ的這個已經爲XML類似這樣

HeaderColumns = (from column in panel.Elements("HeaderColumns").Elements("column") 
       select new Dictionary<int, string>() 
       { 
        (int)column.Attribute("performanceId"), 
        (string)column.Attribute("text") 
       }).ToDictionary<int,string>(), 

的東西,但這並不工作,因爲

  1. ToDictionary()需要函數求參數,我不知道 那是什麼/如何實現它, 和
  2. 無論如何,代碼可能是錯誤的!

請問有人能建議我如何才能達到我需要的效果?謝謝。

編輯:我試過在下面實現Spender的解決方案解決方案,但我很難理解我需要在代碼中進行更改。有人可以澄清嗎?由於

+0

你有沒有得到一個答案,你可以用你的上一個問題? – 2010-04-28 22:49:29

+0

我做了 - 問題和代碼相似但最終不同,所以我就這樣問了一個單獨的問題。 – DaveDev 2010-04-28 23:08:17

回答

2

這是未經測試,但應該做的伎倆:

panel 
    .Elements("HeaderColumns") 
    .Elements("column") 
    .ToDictionary(
     column=>(int)column.Attribute("performanceId"), 
     column=>(string)column.Attribute("text") 
    ) 

在這種情況下,我用下面overload of ToDictionary

public static Dictionary<TKey, TElement> ToDictionary<TSource, TKey, TElement>(
    this IEnumerable<TSource> source, 
    Func<TSource, TKey> keySelector, 
    Func<TSource, TElement> elementSelector 
) 

所以,在這裏source是:

panel 
    .Elements("HeaderColumns") 
    .Elements("column") 

And keySelector and elementSelector are f unctions稱取類型TSource的元素(來自source),並返回從元件得到的值(委託):

keySelector

 column=>(int)column.Attribute("performanceId") 

elementSelector

 column=>(string)column.Attribute("text") 

這些被宣佈採用lambda格式。然後從這些代表的返回類型推斷字典的類型。在這種情況下,這將是Dictionary<int,string>

通用委託Func<TSource, TKey>將定義一個方法的類型,該方法需要一個TSource類型的參數並返回一個TKey類型的值。掌握Linq擴展方法的具體工作時間意味着什麼纔是最重要的。

+0

嗨斯佩德 - 謝謝你,但我有點難以理解我需要在這裏做什麼。有什麼機會可以解釋一點嗎?謝謝 – DaveDev 2010-05-13 10:23:21

1

很難給出一個完整的答案,因爲你的XML和C#不匹配;但每個「HeaderColumns」你可以使用:

var columns = from column in headerColumns.Elements("column") 
       select new { 
        PerformanceId = (int)column.Attribute("performanceId"), 
        Text = (string)column.Attribute("text") 
       }; 
Dictionary<int, string> myHeaders = columns.ToDictionary(
    column => column.PerformanceId, column => column.Text); 

如果你有多個<HeaderColumns>,然後SelectMany也許......

var columns = from panel in doc.Elements("PerformancePanel") 
       from headers in panel.Elements("HeaderColumns") 
       from column in headers.Elements("column") 
       select new { 
        PerformanceId = (int)column.Attribute("performanceId"), 
        Text = (string)column.Attribute("text") 
       }; 
Dictionary<int, string> myHeaders = columns.ToDictionary(
    column => column.PerformanceId, column => column.Text); 
+0

你是對的馬克 - 我沒有意識到我沒有包含完整的XML片段 - 我現在已經糾正它。謝謝 – DaveDev 2010-04-28 23:00:27

+0

對不起馬克,我拼錯你的名字! - 所以我不會讓我編輯評論。再次感謝。 – DaveDev 2010-04-28 23:07:03