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:
Before XML source modification <city>Brescia</city> <city>Torino</city>
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:
After XML source modification <city>Brescia</city> <city>Torino</city> <city>Dallas</city> <city>Seattle</city>
To get a static result, we can invoke one of the methods we saw in Chapter 4: ToList, ToArray, ToDictionary, or ToLookup.