2010-05-17 87 views
0

我是Linq的新手,我試圖查詢XML文檔以查找特定用戶的客戶經理列表。 (我意識到把它放在數據庫或其他東西中可能更有意義,但這種情況需要一個XML文檔)。Linq to XML:使用元素屬性和值創建一個匿名對象

<user emailAddress='[email protected]'> 
    <accountManager department='Customer Service' title='Manager'>[email protected]</accountManager> 
    <accountManager department='Sales' title='Account Manager'>[email protected]</accountManager> 
    <accountManager department='Sales' title='Account Manager'>[email protected]</accountManager> 
</user> 

我試圖創建的對象與同時包含的XElement的屬性的列表(匿名類型?)屬性(部門,職務)和價值(電子郵件)。我知道我可以得到兩者中的任何一個,但我的問題是選擇兩者。

這裏是我嘗試:

var managers = _xDoc.Root.Descendants("user") 
       .Where(d => d.Attribute("emailAddress").Value == "[email protected]") 
       .SelectMany(u => u.Descendants("accountManager").Select(a => a.Value)); 

foreach (var manager in managers) 
{ 
    //do stuff 
} 

我可以在a.Valuea.Attribute得到,但我無法弄清楚如何讓兩者它們存儲在一個對象。我有一種感覺,它會看起來像這樣:

select new { 
    department = u.Attribute("department").Value, 
    title = u.Attribute("title").Value, 
    email = u.Value 
}; 

回答

3

你是對的。它看起來就像那樣。

例如:

_xDoc.Root.Descendants("user") 
      .Where(d => d.Attribute("emailAddress").Value == "[email protected]") 
      .SelectMany(u => u.Descendants("accountManager")) 
      .Select(a => new { 
       department = a.Attribute("department").Value, 
       title = a.Attribute("title").Value, 
       email = a.Value 
      }); 

編輯:使用查詢理解語法:

from u in _xDoc.Root.Descendants("user") 
where u.Attribute("emailAddress").Value == "[email protected]" 
from a in u.Descendants("accountManager") 
select new { 
       department = a.Attribute("department").Value, 
       title = a.Attribute("title").Value, 
       email = a.Value 
      }); 
+0

AH!我很親密。這很完美,謝謝。 – 2010-05-17 01:33:56

0

如果你想從一個Select方法返回匿名類型,你可以寫:

var managers = 
    _xDoc.Root.Descendants("user") 
     .Where(d => d.Attribute("emailAddress").Value == "[email protected]") 
     .SelectMany(u => 
      u.Descendants("accountManager") 
      .Select(a => new { 
       Department = u.Attribute("department").Value, 
       Title = u.Attribute("title").Value, 
       Email = u.Value }) 
     ); 

創建ano的語法nymous類型不直接綁定到select關鍵字。您可以使用它,例如像這樣:

var manager = new { Department = "Somewhere", Title = "Mr" }; 

所以,語法a => new { ... }是返回一個新的匿名類型,就像select new { ... }是構建新的匿名類型子句的lambda表達式。

關於點符號和查詢語法之間的選擇 - 這實際上是個人偏好(儘管有些東西看起來比查詢語法更好,但某些方法如Count只能使用點符號)。但是,所有查詢都由編譯器轉換爲方法調用。

0

我假設只有一個用戶sipAddress == sipUri?通過使用.First

.First(d => d.Attribute("sipAddress").Value == sipUri) 

這將獲得其中的謂詞返回true的用戶

var managers = _xDoc.Root 

您可以只選擇第一個元素匹配:

讓我們先從這一點。然後,您需要將元素中的屬性和值提取到新對象(匿名類型)中。

如果有是許多用戶並希望所有列出的經理,這可以通過使用.SelectMany來完成(即,對於每個用戶來說,是許多管理者,選擇所有這些),但在這種情況下,我認爲只有一個,而.First已經返回了非常元素,所以你可以只使用它的屬性來訪問管理

.Descendants("accountManager") 

然後你會得到所有的XElement從所選元素遞減的名單。把它變成另一目的是通過使用從元素的值是通過使用映射函數,在LINQ的,是做.Select

.Select(managerElem => new { 
    department = u.Attribute("department").Value, 
    title = u.Attribute("title").Value, 
    email = u.Value 
}); 

正如我剛纔所說,如果是多個用戶使用正確的sipAddress並且你想要全部的經理人,只需將.Descendants包裝在.SelectMany之內。

.SelectMany(userElem => userElem.Descendants("accountManager")) 

我沒有帶測試代碼,但我相信你就可以按照我寫的東西弄明白。

希望這會有所幫助! :)如果您仍然感到困惑,請隨時在評論中提問。

+0

感謝您的詳細解釋,很有幫助。我還在學習。 – 2010-05-17 01:34:37

相關問題