2011-03-01 14 views
5

Czy istnieje składnia inicjująca dla ExpandoObject, której mogę użyć na swoją korzyść w kwerendzie LINQ do XML dla celów zwięzłości?Krótka droga do osiągnięcia dynamicznych obiektów od zapytania LINQ do XML select?

Uwaga: Wyniki zapytania mają być przekazywane poza zakresem bieżącego zestawu, więc anonimowe typy nie wchodzą w grę (see why here).

Próbuję użyć składni jak krótkie obiektów po stworzyć dynamiczny/EXPANDO:

public IEnumerable<dynamic> ParseUserXml(string strXmlUser) { 

var qClients = 
    from client in xdoc.Root.Element(XKey.clients).Elements(XKey.client) 
    // client object 

    // I cannot get ExpandoObject to initialize inline 
    select new ExpandoObject() {  // try initialization syntax, COMPILE ERR 
     OnlineDetails = new 
     { 
      Password = client.Element(XKey.onlineDetails). 
       Element(XKey.password).Value, 
      Roles = client.Element(XKey.onlineDetails). 
       Element(XKey.roles).Elements(XKey.roleId). 
       Select(xroleid => xroleid.Value) 
      // More online detail fields TBD 
     }, 

     // etc .... 

     // YIELD DYNAMIC OBJECTS BACK THROUGH IEnumerable<dynamic>... 
     foreach (var client in qClients) 
     { 
      yield return client; 
     } 

bardziej zaangażowani rozwiązań, aby ta praca kod może być:

  • stworzyć konkretną klasę i zainicjuj go zamiast tego (ale nie chcę tworzyć wielu takich).
  • użycie anonimowy typ i skopiować jego członków do dynamicznego obiektu (nieco redundantny) i powrót dynamicznych obiektów

Czy jest równie krótki składni, aby osiągnąć to, co zamierzam zrobić błędnego kodu w pytaniu czy będę musiał rozszerzyć bazę kodów w jakiś sposób, aby uzyskać pożądany rezultat?

Odpowiedz

0

skończyło się za pomocą jednego z Jon Skeet's code answers from a related question. Próbka kodu skopiowana tutaj dla potomności. Używa klas surowych zamiast składni zapytań.

// Code answer by Jon Skeet. 
var qClients = xdoc.Root 
     .Element(XKey.clients) 
     .Elements(XKey.client) 
     .Select(client => { 
      dynamic o = new ExpandoObject(); 
      o.OnlineDetails = new ExpandoObject(); 
      o.OnlineDetails.Password = client.Element(XKey.onlineDetails) 
              .Element(XKey.password).Value; 
      o.OnlineDetails.Roles = client.Element(XKey.onlineDetails) 
             .Element(XKey.roles) 
             .Elements(XKey.roleId) 
             .Select(xroleid => xroleid.Value); 
      return o; 
     }); 
1

Niestety nie sądzę, że będziesz w stanie to zrobić. Możesz stworzyć metodę pomocnika i wywołać ją.

var qClients = 
    from client in xdoc.Root.Element(XKey.clients).Elements(XKey.client) 
    // client object 
    select ClientXmlToExpandoObject(client); 

Pomocnik może wyglądać

public dynamic ClientXmlToExpandoObject(System.Xml.Linq.XElement client) 
{ 
    dynamic result = new ExpandoObject(); 
    result.OnlineDetails = new 
     { 
      Password = client.Element(XKey.onlineDetails). 
       Element(XKey.password).Value, 
      Roles = client.Element(XKey.onlineDetails). 
       Element(XKey.roles).Elements(XKey.roleId). 
       Select(xroleid => xroleid.Value) 
      // More online detail fields TBD 
     }; 
    return result; 
}