2011-03-01 19 views
5

Esiste una sintassi di inizializzazione per lo ExpandoObject che posso utilizzare a mio vantaggio in una query LINQ su XML per scopi di brevità?Un modo breve per ottenere oggetti dinamici da LINQ a XML seleziona query?

Nota: i risultati della query devono essere inoltrati al di fuori dell'ambito dell'assembly corrente, pertanto i tipi anonimi non sono disponibili (see why here).

Sto cercando di usare la sintassi breve come gli oggetti seguenti per creare dinamiche/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; 
     } 

soluzioni più coinvolti per fare questo lavoro di codice potrebbe essere:

  • creare classe concreta e inizializzalo invece (ma non voglio crearne un mucchio).
  • uso tipo anonimo e copiare i suoi membri a un oggetto dinamico (un po 'ridondante) e restituire gli oggetti dinamici

C'è un altrettanto breve sintassi per ottenere quello che intendo fare con il codice errato in questione, o dovrò espandere il codice base in qualche modo per ottenere il risultato desiderato?

risposta

0

ho finito per usare uno dei Jon Skeet's code answers from a related question. Esempio di codice copiato qui per i posteri. Usa le classi raw piuttosto che la sintassi della query.

// 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

Purtroppo non penso che sarete in grado di farlo. Quello che puoi fare è creare un metodo di supporto e chiamarlo.

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

L'helper potrebbe essere simile

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; 
} 
Problemi correlati