首页 > 后端开发 > C++ > 为什么 EF Core 导航属性在显式加载之前为空,以及如何一致地填充它们?

为什么 EF Core 导航属性在显式加载之前为空,以及如何一致地填充它们?

Barbara Streisand
发布: 2025-01-24 22:25:09
原创
724 人浏览过

Why are EF Core navigation properties null until explicitly loaded, and how can I consistently populate them?

EF Core 延迟加载导航属性的空值问题及解决方案

问题描述

考虑以下模型:

<code class="language-csharp">public class Mutant
{
    public long Id { get; set; }
    public long OriginalCodeId { get; set; }
    public virtual OriginalCode OriginalCode { get; set; }
}

public class OriginalCode
{
    public long Id { get; set; }
    public virtual List<Mutant> Mutants { get; set; }
}</code>
登录后复制

在 DbContext 的 OnModelCreating 方法中定义关系:

<code class="language-csharp">modelBuilder.Entity<Mutant>()
    .HasOne(m => m.OriginalCode)
    .WithMany(oc => oc.Mutants)
    .HasForeignKey(m => m.OriginalCodeId)
    .OnDelete(DeleteBehavior.Restrict);</code>
登录后复制

当查询 Mutant 时,OriginalCode 属性最初为空。但是,如果在查询 Mutant 之前先查询 OriginalCode,则 OriginalCode 属性会被填充。

原因分析

EF Core 文档的“加载相关数据”部分对此行为进行了说明:

Entity Framework Core 目前不支持延迟加载,因此通常情况下,在您通过预加载或显式加载它们之前,导航属性将为空。

然而,“预加载”部分包含以下内容:

提示 Entity Framework Core 将自动修复任何先前已加载到上下文实例中的其他实体的导航属性。因此,即使您没有显式包含导航属性的数据,如果先前已加载部分或全部相关实体,该属性仍可能被填充。

解决方案

解决第一个问题(导航属性为空):

使用可用的加载相关数据的方法,例如预加载:

<code class="language-csharp">var mutants = db.Mutants.Include(m => m.OriginalCode).ToList();</code>
登录后复制

解决第二个问题(预先加载相关实体导致导航属性被填充):

此行为是“设计使然”,无法控制。为避免此问题:

  • 为每个查询使用新的 DbContext 实例。
  • 使用无跟踪查询 (AsNoTracking())。

EF Core v2.1 及更高版本更新:

EF Core v2.1 支持延迟加载,但默认情况下未启用。要启用它:

  • 将所有导航属性标记为 virtual
  • 安装 Microsoft.EntityFrameworkCore.Proxies NuGet 包。
  • 使用 UseLazyLoadingProxies() 启用延迟加载。

通过以上方法,您可以有效地管理 EF Core 中的导航属性加载,避免空值问题并提高代码的可预测性。

以上是为什么 EF Core 导航属性在显式加载之前为空,以及如何一致地填充它们?的详细内容。更多信息请关注PHP中文网其他相关文章!

来源:php.cn
本站声明
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn
作者最新文章
热门教程
更多>
最新下载
更多>
网站特效
网站源码
网站素材
前端模板