Migrating from LINQ to SQL to Entity Framework: Eager Loading

Since the release of the Entity Framework, we have received a number of requests for details and best practices from customers who are looking at migrating their LINQ to SQL based applications to the Entity Framework.  In order to address this topic, we are beginning a new series of blogs posts that will look at various aspects of migration.

This first post in the series covers Eager Loading in LINQ to SQL, and the steps for migrating to equivalent constructs in the Entity Framework in .NET 3.5 SP1. Subsequent posts will cover Deferred Loading, LINQ specifics, concurrency, mapping, stored procedure support, and other topics. As we continue to approach the next release of the Entity Framework we will revisit how some of the new features aid in migration.

What is Eager Loading?

Eager, or immediate, loading occurs when you query for an object and all of the related objects are also returned. One of the major differences in how LINQ to SQL and the Entity Framework implement eager loading is that LINQ to SQL allows eager loading behavior to be specified at the context level, and the Entity Framework supports it at the query level.

LINQ to SQL allows you to define the eager loading behavior at the Context level. The DataLoadOptions class allows you to define the load behavior and attach it to a context. This defines the eager loading behavior for all entities that are fetched for that particular DataContext instance. For more information, see Deferred versus Immediate Loading (LINQ to SQL).

 DataLoadOptions dataLoadOptions = new DataLoadOptions();
dataLoadOptions.LoadWith<Customer>(c => c.Order);
db.LoadOptions = dataLoadOptions;

List<Customer> customers = db.Customer.ToList();

The Entity Framework allows you to define eager loading at the query level by using the Include method. For more information, see Shaping Query Results.

 List<Customer> customers = db.Customer.Include("Order").ToList();

The scope of eager loading differs between LINQ to SQL and the Entity Framework. LINQ to SQL supports per-context eager loading options and the Entity Framework supports per-query eager loading options.

Using LINQ to SQL for cascading eager loading spanning multiple entity types

In LINQ to SQL, you can define eager loading for any type of entity that is passed with the LoadWith method. For example, you can specify EntitySets that are directly available on an entity as an argument. For each EntitySet that is to be eager loaded, declare a new LoadWith clause and include it as a part of DataLoadOptions.

If this is done for a chain of hierarchy as shown in the below example, Customer ->Loadwith ->Orders->Loadwith ->OrderDetails, we can eagerly load multiple levels in the object graph.

 DataLoadOptions dataLoadOptions = new DataLoadOptions();
dataLoadOptions.LoadWith<Customer>(c => c.Order);
dataLoadOptions.LoadWith<Order>(c => c.OrderDetail);
db.LoadOptions = dataLoadOptions;

List<Customer> customers = db.Customer.ToList();

Cascading Eager Loading in Entity Framework

The Include method allows multiple hierarchies of the EntityCollection to be denoted with dot (.) notation.

 

 List<Customer> customers = 
           db.Customer.Include("Order.OrderDetail").ToList();

In the Entity Framework, a single call of the Include method can eagerly load the multilevel hierarchy in an EntityCollection, per query.

Eager Loading of multiple relationships in LINQ to SQL

In LINQ to SQL, multiple EntitySets can be eagerly loaded with an entity by adding each one of them using the LoadWith method of the DataLoadOptions class and attaching the DataLoadOptions object to the DataContext.

 DataLoadOptions dataLoadOptions = new DataLoadOptions();
dataLoadOptions.LoadWith<Product>(c => c.OrderDetail);
dataLoadOptions.LoadWith<Product>(c => c.Supplier);
db.LoadOptions = dataLoadOptions;

Product firstProduct = db.Product.First();

Eager Loading of multiple relationships in Entity Framework

In the Entity Framework, you can use the Include method multiple times in a query to eager load multiple EntityCollections.

 Product firstProduct = 
       db.Product.Include("OrderDetail").Include("Supplier").First();

LINQ to SQL keeps multiple LoadWith clauses in an array within DataLoadOptions. The Entity Framework allows you to add multiple Include methods on an entity for a particular query.

In our next post, will look at Deferred/Lazy Loading. Stay tuned and let us know what you think!

- The ADO.NET Team