Deferred Query Evaluation
Under the cover, all the extension methods described in the
previous section work with deferred query evaluation, like every other LINQ
query. The consequence of this is that every time we use them, the result can
change if the source XML on which they are applied has been changed. Consider
the example in Listing 6-30, where we
output to the console window all the city nodes of the
customers located in Italy.
Listing 6-30: A
LINQ to XML query to extract all city nodes from a customers list
XElement xmlCustomers = new XElement("customers",
from c in customers
where c.Country == Countries.Italy
select new XElement("customer",
new XElement("name", c.Name),
new XElement("city", c.City),
new XElement("country", c.Country)));
var cities = xmlCustomers.DescendantsAndSelf("city");
Console.WriteLine("\nBefore XML source modification");
foreach (var city in cities) {
Console.WriteLine(city);
}
The result of the query is the following:
Now let’s try to change the content of the xmlCustomers
object. We will add customers that are not located in Italy and then repeat the
iteration over the cities variable, representing the
LINQ query over XElements with the XML name of
city. The code is shown in Listing
6-31.
Listing 6-31: A
LINQ to XML query to extract all city nodes from a customers list after adding
some customers
xmlCustomers.Add(
from c in customers
where c.Country != Countries.Italy
select new XElement("customer",
new XElement("name", c.Name),
new XElement("city", c.City),
new XElement("country", c.Country)));
Console.WriteLine("\nAfter XML source modification");
foreach (var name in names) {
Console.WriteLine(name);
}
This time the result also includes the new cities, which are
outside of Italy:
To get a static result, we can invoke one of the methods we
saw in Chapter 4:
ToList, ToArray,
ToDictionary, or ToLookup.