Короткий способ достижения динамических объектов из LINQ to XML select query? - PullRequest
5 голосов
/ 01 марта 2011

Существует ли синтаксис инициализации для ExpandoObject, который я могу использовать в своих интересах в запросе LINQ to XML для краткости?

Примечание: результаты запроса предназначены для передачи за пределы области текущей сборки, поэтому анонимные типы исключены (, посмотрите, почему здесь ).

Я пытаюсь использовать краткий синтаксис, подобный следующему, для создания динамических / расширяемых объектов:

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 ]

1 голос
/ 01 марта 2011

К сожалению, я не думаю, что вы сможете это сделать. Что вы можете сделать, это создать вспомогательный метод и вызвать его.

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;
}
0 голосов
/ 02 марта 2011

В итоге я использовал один из кодовых ответов Джона Скита на связанный вопрос .Пример кода скопирован здесь для потомков.Он использует необработанные классы, а не синтаксис запроса.

// 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 голосов
/ 01 марта 2011
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...