EntityFramework "Include" Equivalent in LINQ to SQL
(
Oct 27 2008 - 07:19:52 PM by
Timothy Khouri) - [
print blog
post]
Recently at my job, we switched from using DataSets over Web Services to using the EntityFramework over WCF. Within about two days, we switched off of using EF, and went to LINQ to SQL (which is my love really). The point of this post is not to put down EF, but is rather to show how to achieve one of the pieces of functionality in there that I liked... but with LINQ to SQL instead.
EntityFramework's "Include" Method
Because the EntityFramework doesn't support lazy loading, you have to use the "Include" method to retrieve related data in your query. What I mean by this is that if you have a table called "Customers", and a table called "Orders" (which are linked together), this query will not populate the "Orders" data:
MyEntities context = new MyEntities();
var orders = context.Customers
.First().Orders;
but this code will:
MyEntities context = new MyEntities();
var orders = context.Customers
.Include("Orders")
.First().Orders;
This is not new information, but what was new to me is that LINQ to SQL also supports this type of functionality (plus the implementation is better in my opinion).
EF's "Include" Equivalent in LINQ to SQL
You may be wondering, "Since LINQ to SQL supports lazy loading, why would you want to pre-download related data?" And the answer is quite simple: performance and distribution. If you know for a fact that you are going to use the "Orders" data when you pull your customer object, then it's much faster to hit SQL only once and download all the data, then loop through it in memory.
Also (as is in my case), if you are planning on sending the object over a WCF connection (or a typical web-service), then you'll need to have all of the data in the object graph before sending it. Once the object is sent to the client, that's it!
So, how do we achieve the same '.Include("Orders")' functionality? Here's the code:
MyDataContext context = new MyDataContext();
DataLoadOptions options = new DataLoadOptions();
options.LoadWith<Customer>(item => item.Orders);
context.LoadOptions = options;
var orders = context.Customers
.First().Orders;
You have to set your "LoadWith" options *before* you assign the "LoadOptions" property on the context. If you assign the property first, and then call "LoadWith", you'll get the following error: "LoadWith is not allowed after freeze or attach to DataContext."
Conclusion
So to wrap up this short blog post in an even shorter few sentenses, I'll conclude by saying the following: The EntityFramework doesn't support lazy loading. Instead, you have to specifically load relational properties with the "Include" method. LINQ to SQL does support deferred loading, but you can choose to load relational properties at the same time using the "LoadWith" method.