Efcore: DetachedLazyLoadingWarning On Eagerly Fetched Navigation

Created on 10 Feb 2020  路  6Comments  路  Source: dotnet/efcore

When doing an AsNotTracking() query with an eager fetch, EF incorrectly throws a DetachedLazyLoadingWarning when accessing the navigation which was eagerly loaded. This appears to happen when the principle entity is in a hierarchy.

Snippet

var user = await db.Users
    .AsQueryable()
    .AsNoTracking()
    .Include(x => x.PullRequests)
    .FirstOrDefaultAsync();

var prs = user.PullRequests;    // Throws here

*Repro to follow in comment.

Further technical details

EF Core version: 3.1.1
Database provider: Npgsql & InMemory
Target framework: .NET Core 3.1

area-change-tracking closed-fixed customer-reported type-bug

All 6 comments

Run solution and find exception printed in the Console.

EFCoreSandbox.zip

@ajcvickers
Is there no way this gets fixed in a bug fix for 3.1.x?
3.1 is LTS, this is clearly a bug, and it affects every simple no-tracking query w/ Include and a hierarchy.

@Cooksauce It's unlikely since the workaround (i.e. disable the warning) is very easy. If we see multiple customers hitting this, then we will reconsider.

@Cooksauce FYI, the release planning process goes into more details on the patch bar.

@ajcvickers

Can this be marked with the 'regression' label? The query works in 2.2

Here's my case for this under those parameters:

  • Impacts multiple customers: Maybe? It was actually fairly difficult to track down the cause of this. I initially thought I had something configured wrong or my data model wasn't supported. Maybe a case could be made that others have encountered this but not realized what the issue was?
  • Regression: Yes this is a regression, it runs in 2.2
  • Failure causes data corruption: No, but the current proposed workaround might
  • Reasonable workarounds: I would argue that disabling the warning is not a reasonable workaround. _See below_
  • Fix has a high risk of breaking something else: My guess is no, and that this would be simple fix... but I'm not familiar with the internal codebase so I could be wrong on that
  • Bug is in a corner-case: See 'Impacts multiple customers'

Respectfully, I don't agree with disabling the warning (_and will not use that in production_) unless you can point me to what the specific behavior is when the warning should throw, but was disabled. What if, in a different area of code, I actually do try to lazy load on a non-tracked entity? What happens? Does it just return an empty collection? Does it return null?
If it returns an empty collection, how do I know whether the collection is actually empty or I was trying to lazy load on an untracked entity?

Ultimately, I'm just trying to readonly stream a very large collection of entities, and not have the change-tracker slow anything down. Do you have any other workarounds to suggest?

@Cooksauce When the warning was implemented there was debate as to whether it was really useful. EF6 didn't have any such warning. If you disable the warning, then EF will no-op. It won't load the relationship; it won't create any collection that doesn't already exist.

The most likely outcome is that you'll get a null ref exception at the next line in your code instead of this warning. The intention of the warning is to help you track down the issue, but it's not functionally very important.

Was this page helpful?
0 / 5 - 0 ratings