Dela via


Are you Eager? Or are you Lazy? Or are you both on a case to case basis...??

Entity Framework, Eager Loading and Lazy Loading, my own 2 cents. For those new to Entity Framework, we are talking about the patterns that you can use to load related objects. The strategy by which you would load entity objects that are related to the one in question. There is a beautiful resource that mentions it all. I do not think there is any elaboration required in that matter. But this is not the meat of the matter.

image How do you design an application that uses Entity Framework as a data access strategy? There are a no. of things to consider. The apparent answer all over the Internet is the Repository Pattern (ref: https://blogs.infosupport.com/blogs/willemm/archive/2008/08/18/Using-ADO.NET-Entity-framework-with-the-repository-pattern.aspx, https://blogs.microsoft.co.il/blogs/kim/archive/2008/11/12/data-access-with-the-entity-framework.aspx, https://www.simonsegal.net/blog/2009/01/13/entity-framework-repository-specifications-and-fetching-strategies/). The purpose of the repository pattern is "A system with a complex domain model often benefits from a layer, such as the one provided by Data Mapper (165), that isolates domain objects from details of the database access code." All said and done, we write the repository to abstract the CRUD from the Application Layer. This way, simply put, we don't need to write separate routines to do CRUD behaviour on every entity type. The functions look something like this:

------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

/// <summary>
/// Returns the required querable object to the caller
/// </summary>
/// <typeparam name="T">Generic Object</typeparam>
/// <returns>IQueryable<T></returns>
private IQueryable<T> GetTable<T>()
{
IQueryable<T> result = null;
string type = typeof(T).Name;
ObjectQuery query = Context.CreateQuery<T>(type);
result = (IQueryable<T>)query;
return result;
}

This routine is called like this.

////<summary>
////Return all instances of type T.
////</summary>
////<returns></returns>
public virtual IEnumerable<T> All<T>()
{
System.Data.Linq.DataLoadOptions dlo = new System.Data.Linq.DataLoadOptions();
return GetTable<T>();
}

And this in turn is called like this:

public IEnumerable<Employee> GetEmployees()
{
IEnumerable<Employee> employees = this.dbProvider.All<Employee>();
return employees;
}

---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

Now if you see, we have one function retrieve all types of entity objects. Now let's get to the actual topic in hand. Eager loading and lazy loading. I cannot opt for any of the mentioned patterns, because I do not have the type of the pattern that I am going to return at design time. I have already postponed that by using Generics. Just last night I learnt from Daniel Simmons that Framework 4.0 they are planning to add a property to Context object in order to opt in implicit lazy loading.

While I am still trying to figure out a good way of working around eager loading and lazy loading, as of now (before 4.0 arrives) I am firing separate queries to get all types of related objects. And interestingly, once I fire the queries for the related objects and enumerate them, the principal object at hand gets populated with related objects. So next time you want to reference the related objects, just go ahead and use the beautiful sentence completion features such as this: "txtAddressLine1.Text = employee.EmployeeAddress.First().Address.AddressLine1;"