Explicit Loading in Entity Framework

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.

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.

db.Entry(p).Reference(m => m.ProductModel).Load();
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

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.

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

 db.Entry(pm).Collection(p => p.Products).Load();
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

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]
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.

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 DBEntityEntryto 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.

Leave a Comment

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.

Scroll to Top