我正在像这样创建数据库连接:
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.LazyLoadOnDisposedContext警告: 尝试将导航属性“设置”延迟加载到 处置关联的DbContext之后的实体类型'UserProxy'。”。 可以通过传递事件ID来抑制或记录此异常 “ CoreEventId.LazyLoadOnDisposedContextWarning”到 'DbContext.OnConfiguring'中的'ConfigureWarnings'方法或 “ AddDbContext”。
我理解这是什么意思,但这与我对include的理解以及它如何引起热切的加载背道而驰。
我的理解是,在使用include
并通过调用FirstOrDefault
显式访问对象时,急切地加载要立即填充的相关对象,而无需保持db连接的打开状态;但显然并非如此。
在不要求数据库打开的情况下执行此操作的正确方法是什么?
答案 0 :(得分:1)
作者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实例进行对象事务传输时,如果提供了无效的变体,则也将忽略延迟加载的任何不当使用。