Sunday 26 February 2012

LINQ: Differed Queries

LINQ queries, by default, are differed. It means that the original source collection is accessed only when the collection containing the LINQ output is enumerated. Let us see an example.
string[] companies = { "microsoft", "IBM", "oracle", "google", "apple", "facebook" };
//get companies which have 'oo' in them
IEnumerable<string> companiesWithAnO = from c in companies
           where c.Contains("oo")
           select c;
foreach (var item in companiesWithAnO)
{
 Console.WriteLine(item);
}


Output: google, facebook.

Let’s add a new line after the LINQ query.
try
{
 string[] companies = { "microsoft", "IBM", "oracle", "google", "apple", "facebook" };
 //get companies which have 'oo' in them
 IEnumerable<string> companiesWithAnO = from c in companies
       where c.Contains("oo")
       select c;
 //set IBM string to null
 companies[5] = null;
 foreach (var item in companiesWithAnO)
 {
  Console.WriteLine(item);
 }
}
catch (Exception ex)
{
 Console.WriteLine(ex.ToString());
}

O/P: Google, System.NullReferenceException…

So the first string “Google” is printed, but the next one gives error. Why? The reason is: when the LINQ query output variable – companiesWithAnO is enumerated, it accesses the original source collection – companies to get the results.

Let us check what the variable companiesWithAnO contains after the LINQ query but before the loop. Now we could check the companiesWithAnO.Count(), but this will give the output as 2, because running Count() will enumerate the collection – we need to prove that the collection companiesWithAnO hasn’t been enumerated and the original source not accessed yet.

We can try to have a look at the variable in debug mode, a breakpoint is set before the foreach loop.

image
The ‘Results View’ is not shown as it not yet enumerated. We change the query and add a ToArray().
IEnumerable<string> companiesWithAnO = (from c in companies
     where c.Contains("oo")
     select c).ToArray();

image

So the collection companiesWithAnO contains the values in this case.

Well we know now that LINQ queries are differed queries, except when we use ToArray() or ToList() or ToLookUp(). But why? We shall try that in next post.

No comments:

Post a Comment

Note: only a member of this blog may post a comment.

Shorts - week 3, 2022

Post with links to what I am reading: 1. A very good post on different aspects of system architecture: https://lethain.com/introduction-to-a...