实现从 LINQ 到 XML 的动态对象选择查询的快捷方式?

发布于 2024-10-19 22:59:24 字数 1388 浏览 2 评论 0原文

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

注意:查询的结果旨在传递到当前程序集的范围之外,因此不可能使用匿名类型(在这里查看原因)。

我正在尝试使用如下所示的简短语法来创建动态/扩展对象:

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

更多涉及的解决方案使此代码工作可能是:

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

是否有同样短的语法来实现我打算通过相关错误代码执行的操作,或者我是否必须扩展代码库以某种方式获得所需的结果?

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 fields 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?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

信愁 2024-10-26 22:59:25

我最终使用了 Jon Skeet 的代码答案之一来自相关问题。代码示例复制到此处供后代使用。它使用原始类而不是查询语法。

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

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; 
       });
一杯敬自由 2024-10-26 22:59:24

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

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

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;
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文