从LINQ到XML选择查询实现动态对象的简短方法?

时间:2011-03-01 19:38:18

标签: c# .net linq-to-xml initialization expandoobject

是否有ExpandoObject的初始化语法,为了简洁起见,我可以在LINQ to XML查询中使用它?

注意:查询的结果旨在传递到当前程序集的范围之外,因此匿名类型是不可能的(see why here)。

我正在尝试使用如下的简短语法来创建动态/ 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;
        }

使这段代码更有效的解决方案可能是:

  • 创建具体类并初始化它(但我不想创建一堆那些)。
  • 使用匿名类型并将其成员复制到动态对象(有点多余)并返回动态对象

是否有一个同样短的语法来实现我想要通过错误的代码做的事情,或者我是否必须以某种方式扩展代码库以获得所需的结果?

3 个答案:

答案 0 :(得分:1)

不幸的是,我不认为你能做到这一点。你可以做的是创建一个帮助方法并调用它。

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

助手可能看起来像

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

答案 1 :(得分:0)

答案 2 :(得分:0)

我最终使用Jon Skeet's code answers from a related question之一。此处复制的代码示例用于后代。它使用原始类而不是查询语法。

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