开发者

Short way to achieve dynamic objects from LINQ to XML select query?

Is there an initialization syntax to the ExpandoObject that I can use to my advantage in a LINQ to XML query for brevity purposes?

Note: The results of the query are intended to be passed outside the scope of the current assembly so anonymous types are out of the question (see why here).

I'm trying to use brief syntax like the following to create dynamic/expando objects:

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 fi开发者_StackOverflow中文版elds TBD
        },

        // etc ....

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

More involved solutions to make this code work might be:

  • create concrete class and initialize it instead (but I don't want to create a bunch of those).
  • use anonymous type and copy its members to a dynamic object (somewhat redundant) and return the dynamic objects

Is there an equally short syntax to achieve what I intend to do by the erroneous code in question, or will I have to expand the code base in some manner to get the desired result?


Unfortunately I don't think you'll be able to do this. What you can do is create a helper method and call it.

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

The helper might look something like

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


Here is cool solution, DynamicXml: http://blogs.captechconsulting.com/blog/kevin-hazzard/fluent-xml-parsing-using-cs-dynamic-type-part-1


I ended up using one of Jon Skeet's code answers from a related question. Code sample copied here for posterity. It uses the raw classes rather than query syntax.

// 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; 
       });
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜