Lazy Loading With LINQ
I’ve been following Rob Conery’s ASP.NET MVC Storefront project that he has been broadcasting to the world via webcasts. This project has been going on for over 6 months now and there are currently over 20 videos to watch if you really want to get up fully up to speed (which will literally take days).
Anyway, it’s a Storefront website application built on technologies such as Windows Workflow, ASP.NET MVC, CardSpace, StructureMap, PayPal Standard, OpenID, and many others. While slowly connecting all of these technologies together, Rob attempts to really learn TDD at the same time. He’s an employee of Microsoft.
One of the things that I really like that he did was to modify the Repository Pattern slightly by adding in Pipes and Filters Pattern on top of it using the IQueryable<> generic in LINQ. It really is brilliant in my opinion, and if you want to get totally up to speed with just this small part of his project, watch the first 3-5 videos of Rob’s Storefront project. Then read a blog post by him about an issue he ran into and how he fixed it; the link to his post is at the bottom of this blog entry.
In the process of making this new Repository pattern, he came across some issues with trying to do true Lazy Loading of an object’s relationships to other objects within his LINQ queries. Basically he wanted to harness the power of IQueryable used by LINQ queries to create the expression that queries against the database but not execute it unless needed. For instance, if you’ve got a Product object in your model and it contains a collection of UserRating objects, there will be times when you want to retrieve a Product with its UserRatings and times when you only need the Product. The most efficient way to do it (and coolest) would be to retrieve the object and its relationships the same way every time and let the IQueryable magic of LINQ know when to execute the query against the database and when to leave it as an unexecuted expression.
So Rob created the LazyList object that holds the IQueryable expression until you need to iterate over it or retrieve one of its elements, where it executes the query and fetches real data from the data source. Rob ran into some unexpected issues with the relationships not loading lazily but was able to solve the problem by using the keyword let in LINQ. Read his full post about the issues and fixes (and get the source code for the LazyList class) at the following link: