Linq: от XML до IEnumerable> Отсроченное исполнение? - PullRequest
1 голос
/ 06 августа 2010

Я пытаюсь вытянуть Roles ниже в IEnumerable<KeyValuePair<int, string>>

<PROJECT PROJECT_NO="161917"> 
  <CONTACT CLIENT_ID="030423253272735482765C" CONTACT_NO="1"> 
    <ROLE ROLE_ID="2" ROLE_DESC="ARCHITECT" /> 
    <ROLE ROLE_ID="5" ROLE_DESC="INTEGRATOR" /> 
  </CONTACT>
</PROJECT>



private static ProjectContact BuildProjectContactFromXml(XElement xml)
    {
        ProjectContact projectContact = new ProjectContact();
        projectContact.ProjectId = SafeConvert.ToInt32(xml.Attribute("PROJECT_NO").Value);
        projectContact.Roles = xml.Elements()
                                    .First()
                                    .Elements()
                                    .Select(role => new KeyValuePair<int, string>(
                                                            SafeConvert.ToInt32(role.Attribute("ROLE_ID").Value), 
                                                            role.Attribute("ROLE_DESC").Value));

        return projectContact;
    }

Мой вопрос касается отложенного выполнения этого оператора Linq.Насколько я понимаю, когда я возвращаю этот ProjectContact, оператор Linq еще не выполнен.Есть ли способ заставить выполнение этого оператора так, чтобы это происходило в этом методе, а не когда кто-то пытается получить доступ к ролям?Я думаю, что мог бы принудительно выполнить оператор, вызвав для него .Count (), но, похоже, должен быть лучший способ.

Ответы [ 2 ]

2 голосов
/ 06 августа 2010

Если тип данных .Roles является массивом, вы можете просто добавить .ToArray() после вашего .Select(), и это обеспечит выполнение запроса.

В любом случае, вы можете выполнить ToList() или .ToArray(), и вы получите выполнение запроса.

2 голосов
/ 06 августа 2010

projectContact.Roles будет IEnumerable<KeyValuePair<int, string>> - это то, что вы хотите, или вы хотите, чтобы это был список или словарь?Для списка просто нажмите .ToList() в конце оператора.

Для словаря это немного сложнее:

   projectContact.Roles = xml.Elements() 
                                .First() 
                                .Elements()
                                .ToDictionary(
                 role=> SafeConvert.ToInt32(role.Attribute("ROLE_ID").Value),
                 role=> role.Attribute("ROLE_DESC").Value)); 

ОБНОВЛЕНИЕ: В ваших комментариях вы утверждаете, что Roles IDIEnumerable<KeyValuePair<int, string>>.Технически это может быть словарь или список, хотя в первом случае вы действительно не можете использовать его словарь через этот интерфейс.В этом случае вы можете использовать большую часть его List-ness в последнем случае - но, похоже, вам определенно не нужна эта способность.

Итак, придерживайтесь .ToList();.Это будет Список за кулисами, но, не вдаваясь в дополнительные подробности, пользователи все равно смогут использовать его только как IEnumerable.

...