Fabrice's weblog

Tools and Source

News


Read sample chapters or buy LINQ in Action now!
Our LINQ book is also available on AMAZON

.NET jobs

Emplois .NET

The views expressed on this weblog are mine alone and do not necessarily reflect the views of my employer. The content of this weblog is independent from Microsoft or any other company. transatlantys hot news

Contact

Me

Others

Selected content

Use the power of let in your LINQ queries

Often, when you try to find out how to write the correct LINQ query you need, you end up being confused because it becomes too complex. In such situations, you should remember that the let clause is here to help you.

Let's see is an example from the official LINQ forum.
Someone asked how to query the following XML document:

<cars>
  <car name="Toyota Coupe">
    <profile name="Vendor" value="Toyota"/>
    <profile name="Model" value="Celica"/>
    <profile name="Doors" value="2"/>
    <support name="Racing" value="yes"/>
    <support name="Towing" value="no"/>
  </car>
  <car name="Honda Accord Aerodec">
    <profile name="Vendor" value="Honda"/>
    <profile name="Model" value="Accord"/>
    <profile name="Doors" value="4"/>
    <support name="Racing" value="no"/>
    <support name="Towing" value="yes"/>
  </car>
</cars>

Here is one way to do it:

from car in root.Elements("car")
let profiles =
  from profile in car.Elements("profile")
  select new {
    Name = profile.Attribute("name").Value,
    Value = profile.Attribute("value").Value
  }
let supports =
  from support in car.Elements("support")
  select new {
    Name = support.Attribute("name").Value,
    Value = support.Attribute("value").Value
  }
select new Car {
  Name = car.Attribute("name").Value,
  Vendor = profiles.Single(prof => prof.Name == "Vendor").Value,
  Model = profiles.Single(prof => prof.Name == "Model").Value,
  Doors = int.Parse(profiles.Single(prof => prof.Name == "Doors").Value),
  RacingSupport = supports.Single(sup => sup.Name == "Racing").Value == "yes"
};

It's easier to isolate the "profile" and "support" elements in separate sequences using let clauses, as above. Then the select clause becomes simple to write.

As Luke Hoban explains on his blog: 

With let query clauses, you can introduce a variable into scope and use it in the subsequent query clauses. Similar to local variables in a method body, this gives you a way to avoid evaluating a common expression multiple times by storing it in a variable. This can be very useful even in much simpler queries. Of course, in the query above - let is absolutely critical.

The "query above" he refers to is a ray tracer coded as a big LINQ query full of let clauses!


Cross-posted from http://LinqInAction.net

Comments

No Comments

Leave a Comment

(required) 

(required) 

(optional)

(required)