I am creating the db connection like so:
protected override void OnConfiguring(DbContextOptionsBuilder optionbuilder)
{
optionbuilder.UseLazyLoadingProxies().UseSqlite(@"Data Source=Data.db");
}
And I am trying to access an object like so:
public static User GetProfile(int uid)
{
using (Db db = new Db())
{
return db.Users.Include(x => x.Settings).FirstOrDefault(x => x.UserId == uid);
}
}
The user object is as follows:
public class User
{
[Key]
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public int UserId { get; set; }
public string Name { get; set; }
public DateTime? LastUsed{ get; set; }
public virtual Setting Settings { get; set; }
}
but upon accessing Users.Settings
, it throws the following error:
'Error generated for warning 'Microsoft.EntityFrameworkCore.Infrastructure.LazyLoadOnDisposedContextWarning: An attempt was made to lazy-load navigation property 'Settings' on entity type 'UserProxy' after the associated DbContext was disposed.'. This exception can be suppressed or logged by passing event ID 'CoreEventId.LazyLoadOnDisposedContextWarning' to the 'ConfigureWarnings' method in 'DbContext.OnConfiguring' or 'AddDbContext'.'
I understand what this means but it goes against my understanding of includes and how it causes eager loading.
My understanding was that when using an include
and accessing the object explicitly by calling FirstOrDefault
eager load the related objects to be populated immediately without the need for the db connection to remain open; but apparently, this is not the case.
What would be the right way to do this without requiring the database be left open?
Auther V, a developer working on EFC has confirmed that this is a bug.
https://github.com/aspnet/EntityFrameworkCore/issues/15170
Documentation about this change
It is fixed in EF Core 3.0.0 RC4 but as of writing this, is not available in the public domain. I personally would not suggest using RC4 as it is still in development and is not well suited for general purpose or production use.
For now, you can suppress the error like so:
protected override void OnConfiguring(DbContextOptionsBuilder optionbuilder)
{
optionbuilder.UseSqlite(@"Data Source=Data.db").UseLazyLoadingProxies();
optionbuilder.ConfigureWarnings(w => w.Ignore(CoreEventId.LazyLoadOnDisposedContextWarning));
}
The optionbuilder.ConfigureWarnings(w => w.Ignore(CoreEventId.LazyLoadOnDisposedContextWarning));
line is what you'd need.
But please be aware that any improper usage of lazy loading will also be ignored providing nulled variants when object traveseral is attempted for closed DBContext instances.
来源:https://stackoverflow.com/questions/55369146/eager-loading-include-with-using-uselazyloadingproxies