Linq: Xml to IEnumerable<KeyValuePair<int, string>> deferred execution?
I'm trying to pull out the Roles
below into an 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;
}
My question is about deferred execution of this Linq statement. It is my understanding that when I return t开发者_StackOverflow社区his ProjectContact, the Linq statement has not yet executed. Is there a way to force the execution of this statement so that it happens in this method, rather than when someone tries to access the Roles? I think I could force the execution of the statement by calling .Count() on it, but it seems like there should be a better way.
projectContact.Roles
is going to be a IEnumerable<KeyValuePair<int, string>>
is that what you want, or do you want it as a List or DIctionary? For a List, just tack .ToList()
at the end of the statement.
For a Dictionary, it's a bit trickier:
projectContact.Roles = xml.Elements()
.First()
.Elements()
.ToDictionary(
role=> SafeConvert.ToInt32(role.Attribute("ROLE_ID").Value),
role=> role.Attribute("ROLE_DESC").Value));
UPDATE: In you comments you state that Roles id IEnumerable<KeyValuePair<int, string>>
. Technically, that could be either a Dictionary or a List, although in the former case, you really can't use it's Dictionary-ness via that interface. For that matter, you can use much of it's List-ness in the latter case -- but it seems you specifically don't want that ability.
So, tack on .ToList();
. It will be a List behind the scenes, but without going to extradinary lengths, users will still only be able to use it as an IEnumerable.
If the datatype of .Roles
is array, you could simply append .ToArray()
after your .Select()
, and that would ensure that the query is executed.
Either way, you can execute a ToList()
or .ToArray()
, and you'll get execution of the query.
精彩评论