EF Core延迟加载怎么用 EF Core Lazy Loading配置方法

来源:这里教程网 时间:2026-02-21 17:35:27 作者:

EF Core 默认不启用延迟加载,要用它得手动配三样东西:装包、启代理、标 virtual。核心就一句话——访问导航属性时才查数据库,但容易引发 N+1 查询,生产环境慎用

安装 Microsoft.EntityFrameworkCore.Proxies 包

这是启用延迟加载的前提,没有它,

UseLazyLoadingProxies()
方法根本不存在。

用 NuGet 命令安装:
Install-Package Microsoft.EntityFrameworkCore.Proxies
或在 .csproj 文件中添加引用:
<packagereference include="Microsoft.EntityFrameworkCore.Proxies" version="8.0.10"></packagereference>
(版本建议匹配你当前 EF Core 版本)

在 DbContext 中启用代理支持

必须显式调用

UseLazyLoadingProxies()
,否则即使实体标了
virtual
也无效。

OnConfiguring
中配置(适合简单场景):

protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)<br>{<br>  optionsBuilder<br>    .UseSqlServer("YourConnectionString")<br>    .UseLazyLoadingProxies();<br>}

在 ASP.NET Core 的
Program.cs
Startup.cs
中配置(推荐):

builder.Services.AddDbContext<AppDbContext>(options =><br>  options.UseSqlServer(connectionString)<br>    .UseLazyLoadingProxies());

实体导航属性必须声明为 virtual

EF Core 需要通过运行时生成代理子类来拦截属性访问,只有

virtual
成员才能被重写。

集合导航属性示例:
public virtual ICollection<post> Posts { get; set; }</post>
引用导航属性示例:
public virtual Blog Blog { get; set; }
注意:不能是
private set
init
,getter/setter 都得可重写;初始化如
= new List<post>()</post>
可以保留,不影响延迟逻辑

替代方案:不用代理也能延迟加载(ILazyLoader 注入)

适合不想依赖代理、或需更精细控制加载时机的场景。原理是把加载逻辑交给构造函数注入的

ILazyLoader
实例。

实体需提供带
ILazyLoader
的构造函数,并用它加载私有字段:

public class Blog<br>{<br>  private readonly ILazyLoader _lazyLoader;<br>  private ICollection<Post> _posts;<br><br>  public Blog(ILazyLoader lazyLoader) => _lazyLoader = lazyLoader;<br><br>  public virtual ICollection<Post> Posts<br>    => _lazyLoader.Load(this, ref _posts);<br>}

该方式无需
virtual
属性(但仍需
virtual
getter 以支持代理机制兼容),也不依赖动态代理,更可控,但代码稍多

基本上就这些。配置不复杂但容易忽略细节,比如漏装包、忘加

virtual
、或在上下文已释放后访问导航属性导致异常。真要兼顾性能和可维护性,多数场景建议优先用
Include
+
ThenInclude
显式加载。

相关推荐