gpt4 book ai didi

c# - 当我尝试使用 .Include() 进行预加载时,EF Core 是延迟加载

转载 作者:行者123 更新时间:2023-11-30 21:27:29 37 4
gpt4 key购买 nike

我正在使用 EF Core 2.2.6(数据库优先),似乎只是启用延迟加载让我无法进行预加载。启用延迟加载是否会排除以任何容量使用预加载?

namespace Example.Models
{
public class Lead
{
public int Id { get; set; }
public LeadOrganization LeadOrganization { get; set; }

public Lead(ExampleContext.Data.Lead dbLead)
{
Id = dbLead.Id;
LeadOrganization = new LeadOrganization(dbLead.LeadOrganization);
}

public static Lead GetLead(int id)
{
using (var db = new ExampleContext())
{
var dbLead = db.Leads
.Include(l => l.LeadOrganization)
.ThenInclude(lo => lo.LeadOrganizationAddresses)
.ThenInclude(loa => loa.AddressType)
.FirstOrDefault(l => l.Id== id);

return new Lead(dbLead);
}
}
}
}
namespace Example.Models
{
public class LeadOrganization
{
public IEnumerable<LeadOrganizationAddress> Addresses { get; set; }

public LeadOrganization(ExampleContext.Data.LeadOrganization dbLeadOrganization)
{
Addresses = dbLeadOrganization.LeadOrganizationAddresses.Select(loa => new LeadOrganizationAddress(loa));
}
}
}
namespace Example.Models
{
public class LeadOrganizationAddress
{
public AddressType AddressType { get; set; }

public LeadOrganizationAddress(ExampleContext.Data.LeadOrganizationAddress dbLeadOrganizationAddress)
{
AddressType = new AddressType(dbLeadOrganizationAddress.AddressType);
}
}
}
namespace Example.Models
{
public class AddressType
{
public short Id { get; set; }

public AddressType(ExampleContext.Data.AddressType dbAddressType)
{
Id = dbAddressType.Id;
}
}
}

ExampleContext.Data 命名空间包含 EF 从数据库生成的分部类。 LeadLeadOrganizationLeadOrganizationAddressAddressType 基本上是 1:1 的类属性,但添加了静态方法(是的,这很奇怪,但这是我必须使用的)。

Lead 有一个 LeadOrganization,LeadOrganization 又至少有一个 LeadOrganizationAddress,而 LeadOrganizationAddress 又有一个 AddressType。

GetLead 调用 Lead 构造函数时,查询中的数据尚未加载,尽管它应该预先加载。这会导致嵌套对象的问题。当它最终到达 LeadOrganizationAddress 构造函数时,DbContext 已被释放,因此无法延迟加载关联的 AddressType

我是不是误解了预加载的全部意义?我认为它会在初始查询时检索所有数据,然后让我毫无问题地将其传递给构造函数。我不需要继续返回数据库并延迟加载任何内容。

如果启用了延迟加载,是否可以简单地不进行预加载?是否有其他解决方法,例如强制它加载任何代理实体?

最佳答案

好的,在调查问题后,EF Core 2.x 延迟加载通过代理实现存在问题。相关的跟踪问题是

问题是导航属性急切加载的,但是LazyLoader不知道在处理时 - 无法安全地访问上下文更改跟踪器并且只是抛出异常.相关代码可见here ,在第一行:

if (_disposed)
{
Logger.LazyLoadOnDisposedContextWarning(Context, entity, navigationName);
}

当我读到它时,它应该在 EF Core 3.0 中修复,并带有以下“重大更改”- Lazy-loading proxies no longer assume navigation properties are fully loaded .它还部分解释了当前的问题:

Old behavior

Before EF Core 3.0, once a DbContext was disposed there was no way of knowing if a given navigation property on an entity obtained from that context was fully loaded or not.

不幸的是,这不能帮助您解决当前的问题。我看到的选项是:

  1. 等待 EF Core 3.0 发布
  2. 不要通过代理使用延迟加载
  3. 关闭 lazy loading on disposed context 警告 - 默认为 Throw,将其更改为 LogIgnore,例如:

    optionsBuilder.ConfigureWarnings(warnings => warnings
    .Log(CoreEventId.LazyLoadOnDisposedContextWarning)
    );

关于c# - 当我尝试使用 .Include() 进行预加载时,EF Core 是延迟加载,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57664047/

37 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com