Explicit Loading is a technique we query and load the related entities with an explicit call. Explicit loading works very similar to Lazy Loading, but the loading of the related entities happens only after an explicit call. The loading only when we invoke the Load
method of the related entity’s DBEntityEntry
object. In eager loading, we query the related entities along with the main entity in a single Query. In Lazy loading, EF loads the load related entities whenever we access the related Property.
Table of Contents
Explicit Loading in Entity Framework
To make an explicit call to load a related entity, we use the Load
method of the related entity’s DBEntityEntry
object. This object provides information about the entity. The DBContext.Entry()
method returns the DBEntityEntry
of a given entity
In the following query, we retrieve five products from the database. Inside the for loop, we use the load
method to retrieve the ProductModel
Note use the Reference
method as the ProductModel
reference navigational property.
1 2 3 | db.Entry(p).Reference(m => m.ProductModel).Load(); |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 | using (AdventureWorks db = new AdventureWorks()) { //Disable Lazy Loading db.Configuration.LazyLoadingEnabled = false; //Log Database db.Database.Log = Console.Write; //List of Products queried here. var product = (from p in db.Products orderby p.ProductID descending select p).Take(5).ToList(); foreach (var p in product) { //Product model is retrieved here db.Entry(p).Reference(m => m.ProductModel).Load(); Console.WriteLine("{0} {1} Product Model => {2}", p.ProductID, p.Name, (p.ProductModel == null) ? "" : p.ProductModel.Name); Console.ReadKey(); } } |
The corresponding SQL
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 | SELECT TOP (5) [Extent1].[ProductID] AS [ProductID], [Extent1].[Name] AS [Name], [Extent1].[ProductNumber] AS [ProductNumber], [Extent1].[MakeFlag] AS [MakeFlag], [Extent1].[FinishedGoodsFlag] AS [FinishedGoodsFlag], [Extent1].[Color] AS [Color], [Extent1].[SafetyStockLevel] AS [SafetyStockLevel], [Extent1].[ReorderPoint] AS [ReorderPoint], [Extent1].[StandardCost] AS [StandardCost], [Extent1].[ListPrice] AS [ListPrice], [Extent1].[Size] AS [Size], [Extent1].[SizeUnitMeasureCode] AS [SizeUnitMeasureCode], [Extent1].[WeightUnitMeasureCode] AS [WeightUnitMeasureCode], [Extent1].[Weight] AS [Weight], [Extent1].[DaysToManufacture] AS [DaysToManufacture], [Extent1].[ProductLine] AS [ProductLine], [Extent1].[Class] AS [Class], [Extent1].[Style] AS [Style], [Extent1].[ProductSubcategoryID] AS [ProductSubcategoryID], [Extent1].[ProductModelID] AS [ProductModelID], [Extent1].[SellStartDate] AS [SellStartDate], [Extent1].[SellEndDate] AS [SellEndDate], [Extent1].[DiscontinuedDate] AS [DiscontinuedDate], [Extent1].[rowguid] AS [rowguid], [Extent1].[ModifiedDate] AS [ModifiedDate] FROM [Production].[Product] AS [Extent1] ORDER BY [Extent1].[ProductID] DESC |
The EF Generates the following Query in the load
method.
1 2 3 4 5 6 7 8 9 10 11 | SELECT [Extent1].[ProductModelID] AS [ProductModelID], [Extent1].[Name] AS [Name], [Extent1].[CatalogDescription] AS [CatalogDescription], [Extent1].[Instructions] AS [Instructions], [Extent1].[rowguid] AS [rowguid], [Extent1].[ModifiedDate] AS [ModifiedDate] FROM [Production].[ProductModel] AS [Extent1] WHERE [Extent1].[ProductModelID] = @EntityKeyValue1 |
Loading Collections
We use the reference
method if the navigation property is of reference
type. In the case of collection
navigation property, the collection
method is to be used
The Products
is a collection navigation property the entity ProductModel
. The following example retrieves the ProductModel
and then uses the load
method to explicitly load the Products
. Since it is a collection navigation property we make use of the Collection
method
1 2 3 | db.Entry(pm).Collection(p => p.Products).Load(); |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 | using (AdventureWorks db = new AdventureWorks()) { db.Configuration.LazyLoadingEnabled = false; db.Database.Log = Console.Write; var productModel = (from pm in db.ProductModels select pm).Take(5).ToList(); foreach (var pm in productModel) { db.Entry(pm).Collection(p => p.Products).Load(); foreach (var p in pm.Products) { Console.WriteLine(" {0}", p.Name); } } } |
The SQL Queries
1 2 3 4 5 6 7 8 9 10 | SELECT TOP (5) [c].[ProductModelID] AS [ProductModelID], [c].[Name] AS [Name], [c].[CatalogDescription] AS [CatalogDescription], [c].[Instructions] AS [Instructions], [c].[rowguid] AS [rowguid], [c].[ModifiedDate] AS [ModifiedDate] FROM [Production].[ProductModel] AS [c] |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 | SELECT [Extent1].[ProductID] AS [ProductID], [Extent1].[Name] AS [Name], [Extent1].[ProductNumber] AS [ProductNumber], [Extent1].[MakeFlag] AS [MakeFlag], [Extent1].[FinishedGoodsFlag] AS [FinishedGoodsFlag], [Extent1].[Color] AS [Color], [Extent1].[SafetyStockLevel] AS [SafetyStockLevel], [Extent1].[ReorderPoint] AS [ReorderPoint], [Extent1].[StandardCost] AS [StandardCost], [Extent1].[ListPrice] AS [ListPrice], [Extent1].[Size] AS [Size], [Extent1].[SizeUnitMeasureCode] AS [SizeUnitMeasureCode], [Extent1].[WeightUnitMeasureCode] AS [WeightUnitMeasureCode], [Extent1].[Weight] AS [Weight], [Extent1].[DaysToManufacture] AS [DaysToManufacture], [Extent1].[ProductLine] AS [ProductLine], [Extent1].[Class] AS [Class], [Extent1].[Style] AS [Style], [Extent1].[ProductSubcategoryID] AS [ProductSubcategoryID], [Extent1].[ProductModelID] AS [ProductModelID], [Extent1].[SellStartDate] AS [SellStartDate], [Extent1].[SellEndDate] AS [SellEndDate], [Extent1].[DiscontinuedDate] AS [DiscontinuedDate], [Extent1].[rowguid] AS [rowguid], [Extent1].[ModifiedDate] AS [ModifiedDate] FROM [Production].[Product] AS [Extent1] WHERE [Extent1].[ProductModelID] = @EntityKeyValue1 |
Explicit Loading with Filtering
You can filter the output of load
method by using Query
and Load
methods. For example, in the previous example, you may want to list only the product that has List Price > 30.
1 2 3 | db.Entry(pm).Collection(p => p.Products).Query().Where(p => p.ListPrice > 30).Load(); |
Virtual Property
You do not have the navigation properties as virtual.for the explicit loading to work.
Summary
Explicit Loading uses the Load
method of the DBEntityEntry
to load related data. Here you have full control over how & when the query is sent to the database. You can also filter the query using where
before sending it to the database.