急切加载包括使用UseLazyLoadingProxies

问题描述 投票:2回答:1

我正在创建数据库连接,如下所示:

protected override void OnConfiguring(DbContextOptionsBuilder optionbuilder)
{
    optionbuilder.UseLazyLoadingProxies().UseSqlite(@"Data Source=Data.db");
}

我试图访问这样的对象:

public static User GetProfile(int uid)
{
    using (Db db = new Db())
    {
        return db.Users.Include(x => x.Settings).FirstOrDefault(x => x.UserId == uid);
    }
}

用户对象如下:

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; }
}

但在访问Users.Settings时,它会抛出以下错误:

'为警告生成错误'Microsoft.EntityFrameworkCore.Infrastructure.LazyLoadOnDisposedContextWarning:在关联的DbContext被释放后,尝试在实体类型'UserProxy'上延迟加载导航属性'Settings'。通过将事件ID“CoreEventId.LazyLoadOnDisposedContextWarning”传递给“DbContext.OnConfiguring”或“AddDbContext”中的“ConfigureWarnings”方法,可以抑制或记录此异常。

我理解这意味着什么,但这违背了我对包含的理解以及它如何导致急切加载。

我的理解是,当使用include并通过调用FirstOrDefault eager load显式访问对象时,立即填充相关对象,而不需要db连接保持打开状态;但显然,事实并非如此。

在不要求数据库保持打开的情况下,这样做的正确方法是什么?

c# entity-framework asp.net-core lazy-loading ef-core-2.2
1个回答
1
投票

Auther V是一名从事EFC工作的开发人员,他确认这是一个错误。

https://github.com/aspnet/EntityFrameworkCore/issues/15170

Documentation about this change

它在EF Core 3.0.0 RC4中修复,但截至编写时,在公共域中不可用。我个人不会建议使用RC4,因为它仍处于开发阶段,不适合通用或生产用途。

现在,您可以像这样抑制错误:

protected override void OnConfiguring(DbContextOptionsBuilder optionbuilder)
{
    optionbuilder.UseSqlite(@"Data Source=Data.db").UseLazyLoadingProxies();
    optionbuilder.ConfigureWarnings(w => w.Ignore(CoreEventId.LazyLoadOnDisposedContextWarning));
}

optionbuilder.ConfigureWarnings(w => w.Ignore(CoreEventId.LazyLoadOnDisposedContextWarning));线是你需要的。

但请注意,当尝试关闭DBContext实例的对象traveseral时,任何不正确的延迟加载使用也将被忽略,提供无效变体。

© www.soinside.com 2019 - 2024. All rights reserved.