Eager loading include with using UseLazyLoadingProxies

别来无恙 提交于 2019-12-07 20:16:32

问题


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?


回答1:


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

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!