2011-03-01 13 views
5

¿Hay una sintaxis de inicialización en el ExpandoObject que pueda usar a mi favor en una consulta LINQ a XML para fines de brevedad?¿Manera corta de conseguir objetos dinámicos de la consulta de selección de LINQ a XML?

Nota: Los resultados de la consulta están destinados a pasar fuera del alcance del conjunto actual, por lo que los tipos anónimos están fuera de cuestión (see why here).

Estoy tratando de utilizar breve sintaxis como los objetos siguiente para crear dinámico/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; 
     } 

soluciones más implicadas para hacer este trabajo código podría ser:

  • crear clase concreta e inicializarlo en su lugar (pero no quiero crear muchos de ellos).
  • utilización tipo anónimo y copiar sus miembros a un objeto dinámico (algo redundante) y devolver los objetos dinámicos

¿Existe igualmente una corta sintaxis para lograr lo que se propone hacer el código errónea de que se trate, ¿o tendré que expandir la base del código de alguna manera para obtener el resultado deseado?

Respuesta

0

Terminé usando uno de Jon Skeet's code answers from a related question. Ejemplo de código copiado aquí para la posteridad. Utiliza las clases sin formato en lugar de la sintaxis de la consulta.

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

Desafortunadamente, no creo que puedas hacer esto. Lo que puedes hacer es crear un método de ayuda y llamarlo.

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

El ayudante podría ser algo como

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; 
} 
Cuestiones relacionadas