.NET 中的延迟加载模式在 EF Core 中的应用?

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

在 EF Core 中,延迟加载(Lazy Loading)是一种数据加载策略,它允许你在访问导航属性时才从数据库中加载相关数据,而不是在查询主实体时立即加载。这种模式可以减少初始查询的数据量,提升性能,但需要小心使用以避免“N+1 查询”问题。

启用延迟加载的条件

EF Core 默认不开启延迟加载,要使用该功能,需满足以下条件之一:

实体中的导航属性必须标记为 virtual,以便支持运行时动态代理 安装并启用 Microsoft.EntityFrameworkCore.Proxies DbContext 配置中启用延迟加载代理 例如,通过 NuGet 安装代理包:
Install-Package Microsoft.EntityFrameworkCore.Proxies

然后在 OnConfiguringStartup.cs 中配置上下文:

protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
{
    optionsBuilder
        .UseLazyLoadingProxies() // 启用延迟加载代理
        .UseSqlServer("YourConnectionString");
}

实体定义示例

以下是一个简单的父子关系模型,展示如何定义支持延迟加载的实体:

public class Blog
{
    public int Id { get; set; }
    public string Name { get; set; }
    public virtual ICollection<Post> Posts { get; set; } // virtual 启用延迟加载
}
public class Post
{
    public int Id { get; set; }
    public string Title { get; set; }
    public int BlogId { get; set; }
    public virtual Blog Blog { get; set; } // 导航属性也应为 virtual
}

当你查询 Blog 时,Posts 不会立即加载:

var blog = context.Blogs.FirstOrDefault(b => b.Id == 1);
// 此时 Posts 为空,尚未查询数据库
var posts = blog.Posts; // 访问时才会触发数据库查询

延迟加载的注意事项

虽然延迟加载简化了代码,但也带来一些潜在问题:

容易引发 N+1 查询:循环访问多个博客的帖子时,可能产生大量数据库往返 必须保持 DbContext 在访问导航属性时仍然存活 序列化对象时可能意外触发加载,导致性能下降或循环引用错误 动态代理可能与某些第三方库或自定义构造函数冲突

在 Web 应用中,若在 Controller 外部访问导航属性(如视图或 API 响应序列化),需确保上下文生命周期足够长,或改用显式加载(Load())或预先加载(Include())。

替代方案建议

在多数生产场景中,推荐结合使用以下方式代替纯延迟加载:

Include():使用 Eager Loading 显式加载所需关联数据 Select():投影出所需字段,减少数据传输 Explicit Loading:手动调用 Entry().Collection().Load() 控制加载时机

基本上就这些。延迟加载适合快速原型或简单场景,但在性能敏感或复杂应用中,建议更精确地控制数据加载行为。

相关推荐