预加载包括使用 UseLazyLoadingProxies

Eager loading include with using UseLazyLoadingProxies

我正在像这样创建数据库连接:

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 时,它抛出以下错误:

'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'.'

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

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

在不要求数据库保持打开状态的情况下执行此操作的正确方法是什么?

EFC 开发人员 Auther V 已确认这是一个错误。

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

Documentation about this change

它已在 EF Core 3.0.0 RC4 中修复,但在撰写本文时,在 public 域中不可用。我个人不建议使用 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 实例进行对象遍历时,延迟加载的任何不当使用也将被忽略,提供空变体。