Trxplz0
Trxplz0

Reputation: 371

Lazy loading ignoring Explicit Loading

I have a entity loaded with explicit loading but when i try access the loaded references it is loaded again with lazy loading without where clausule!

The only way i found is disable Lazy Loading which i can't!

I don't understand why it's loading again if i already explicit loaded the references.

Here's a example (i shorted a little bit for demonstration purposes):

        var employee = dbo.Employees
            .Where(m => m.StoreId == SessionContext.Store
                && m.Id == 10)
            .Include(m => m.Person)
            .FirstOrDefault();

        if (employee == null)
        {
            return HttpNotFound();
        }

        dbo.Entry(employee)
            .Collection(m => m.Stocks)
            .Query()
            .Where(m => ...)
            .Load();

        // LAZY LOADING HERE
        foreach (var stock in employee.Stocks)
        {
        }

Upvotes: 3

Views: 780

Answers (2)

Leonel Sanches da Silva
Leonel Sanches da Silva

Reputation: 7220

To work properly, Include() should appear right after the DbSet object:

var employee = dbo.Employees
        .Include(m => m.Person)
        .Include(m => m.Stocks)
        .Where(m => m.Stocks....)
        .FirstOrDefault(m => m.StoreId == SessionContext.Store
            && m.Id == 10);

Upvotes: 0

The One
The One

Reputation: 4784

You have to disable Lazy Load, EF will try to fetch all stocks when you iterate them

Wrap your context with a Using block

using(DbContext dbo=new DbContext())
{
   //Disable lazy loading
   dbo.Configuration.LazyLoadingEnabled=false;
   var employee = GetEmployee()...


   dbo.Entry(employee)
        .Collection(m => m.Stocks)
        .Query()
        .Where(m => ...)
        .Load();

}//Kill the context

    // NO LAZY LOADING HERE
    foreach (var stock in employee.Stocks)//If you don't disable Lazy Loading, EF will try to fetch all stocks
    {
    }

When using the Query method it is usually best to turn off lazy loading for the navigation property. This is because otherwise the entire collection may get loaded automatically by the lazy loading mechanism either before or after the filtered query has been executed.

https://msdn.microsoft.com/en-us/data/jj574232.aspx

Otherwise, if you don't want to disable Lazy Loading, you'll have to do what jbl says

var employeeStocksFiltered = dbo.Entry(employee) .Collection(m => m.Stocks) .Query() .Where(m => ...) .ToList(); 
foreach (var stock in employeeStocksFiltered ) { }

Upvotes: 1

Related Questions