In Entity Framework Navigation properties are used to create associations/relationships among entities. Today I am going to write about the three ways which can be used to load related entities data along with the primary entity. I will not be covering the basics of Entity Framework here in this post and I assume you have some experience with Entity Framework programming model.
I am going to go by an example here, because it will be easy for you to understand and it will be easy for me to explain. I am using the Code First approach in Entity Framework. But if you are using Model First Approach, the concept will be basically the same.
I am creating a console application. There I have following two entity classes and two helper methods. The relationship among these entities are pretty much straight forward. Single Department can have many Employees working in it and a single Employee can belong to only one Department. This particular relationship is defined using two Navigation properties in two entities which are the Employees property in Department entity and the Department property in Employee entity.
Here in the GetEmployees() method in Employee entity, for the Employees Department, I am looking up Departments and filling up some data.
Now I am going to create a derived context which is the class MyContext and it is deriving from DbContext.
I have two properties there which are of type DbSet which models my previously defined two entities. Now inside my Main method I am doing some data access using MyContext. For that again I have a static helper method called AddData().
Here using MyContext, first I am inserting the departments returned from my helper method GetDepartments(). After saving those changes, then I am inserting the employees returned from the GetEmployees() method. Please note that now only I am creating the actual relationship between two entities.
After inserting the data, I am browsing my localdb to check the inserted data.
Here I can see the data inserted and the relationship created between Employee and the Department.
Now let’s move into the actual topic which is querying/loading the data. Inside my Main method, I have the following code which should print out each employees FirstName and the DepartmentName.
Hoping this would print out the data, If I run this code, I am getting the following error.
The error is a classic “Object reference not set to an instance of an object.”. If you debug the project you can easily find out the reason, that is the Department property is still null in the Employee.
|Department is null|
So now we know though the information in primary entity is loaded, the information from related entities are not loaded. Now let’s see how we can load information from related entities. There are three ways to achieve this which are as follows,
- Eagerly Loading
- Explicit Loading
- Lazy Loading
Eagerly loading uses ObjectQuery<T>.Include Method which specifies the related objects to include in the query results (as name suggest we are specifying our keen interest on some particular related entity). So specifically we are saying load mentioned entity details along with the primary entity.
You can either use a LINQ expression or a string to mention the entity. I am always preferring the LINQ Expression over the string.
Explicit loading is accomplished through DbExtensions.Load Method. This is an extension method on IQueryable that enumerates the results of the query. This is equivalent to calling ToList without actually creating the list.
Here for each employee/department I am explicitly loading the department of the employee and employees of the department.
Ok now let’s move into the third and final way which is the most easiest way among all above. For this you will just have to modify your Navigation properties with Virtual key word.
Once you do that, you can use our initial way to query the related entities and you will not see any errors.
Since this can increase performance issues, if you don’t want to enable lazy loading, you can disable lazy loading anytime for your context by specifying following command.
I am uploading the full sample to my SkyDrive, do check it out.