繁体   English   中英

急切加载的实体框架问题

[英]Entity Framework problem with eager loading

在此处输入图像描述 在此处输入图像描述

我想创建一个新的TrackingItem ,但服务器的响应是:

在此处输入图像描述

我不知道如何包含Tenant属性。

使用导航属性时,填充导航属性,而不仅仅是 FK。

您可能会看到的问题是,当您调用代码添加跟踪项时,DbContext 将开始跟踪该实例,但是您只在该实例上设置了 TenantId,而不是 Tenant Navigation 属性。 任何从 DbContext 获取该 TrackingItem 引用并尝试将 go to.Tenant.* 的代码都会得到该异常,因为虽然提供了 TenantID,但没有加载任何租户。 对于一个新实例,我认为延迟加载甚至不会启动,而且您似乎并没有从一开始就启用延迟加载。 (租户未声明为virtual

现在使用通用存储库执行此操作很痛苦,因为您已将 DbContext 包装在特定于跟踪项目的存储库中,因此需要进行一些整理。 使用 DbContext 引用,它需要看起来像:

var tenant = _context.Tenants.Single(x => x.TenantId == tenantId);
var trackingItem = new TrackingItem
{
    Tenant = tenant,
    // .. remaining TrackingItem fields...
}
_context.TrackingItems.Add(trackingItems);
await _context.SaveChangesAsync();

使用导航属性时,我建议不要声明 FK 属性,而是使用 FK 的阴影属性。 与导航属性一起声明 FK 的问题是您有 2 个关系的真实来源(.TenantId 和.Tenant.TenantId),它们可以相互独立地更改。 编辑 FK 时的行为也可能因是否加载导航属性而异。

这也意味着每当您获取 TrackingInstance 时,如果代码要检查 Tenant,要么需要初始化延迟加载,要么您需要记住在加载跟踪实例时预先加载 Tenant:

var trackingItem = _context.TrackingItems
    .Include(x => x.Tenant)
    .Single(x => x.TrackingItemId == trackingItemId);

如果您忘记预先加载租户,启用延迟加载将有助于避免异常,尽管它有其局限性(DbContext 仍然需要在范围内)并且如果您过度依赖它可能会导致显着的性能成本。 (即变得懒惰)

相反,我强烈建议在读取数据时使用 Projection /w SelectProjectTo (Automapper) 填充视图模型,您可能需要相关实体的详细信息。 这会产生更优化的查询,并且您无需担心在处理相关实体时急切加载或延迟加载。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM