Entity Framework Core 运行缓慢或盲目工程师

发布: (2026年1月5日 GMT+8 05:06)
3 min read
原文: Dev.to

Source: Dev.to

Entity Framework Core 是 .NET 生态系统中最具生产力的工具之一。
它让团队能够快速前进、干净地建模领域,并迅速交付功能。你可以在不深入了解数据库内部工作细节的情况下编写代码,这既是优势也是劣势。

EF Core 在项目规模不大时表现很好——但项目一旦扩大,就会出现问题。

  • 更多数据
  • 更多关系
  • 更多边缘情况
  • 更多对性能敏感的路径

此时,问题开始显现,EF 常常被指责。工程师可能会添加额外的索引,但这只能暂时掩盖问题。

根本原因: 工程师根本不知道 EF 查询是如何转换成 SQL 的。

在许多成熟的代码库中,LINQ 查询的编写并未考虑它们如何翻译成 SQL。小规模时这往往不被注意:

  • 记录少
  • 并发低
  • 延迟可接受

但随着数据增长,那些“无辜”的查询可能会变成:

  • 意外的多表连接
  • N+1 查询
  • 全表扫描
  • 过度的内存使用
  • 未优化的执行计划

EF Core 并不隐藏 SQL——它会生成 SQL。如果你不理解生成的 SQL,就等于在盲目编码。

来自生产环境的真实案例

几年前,在调查生产系统的性能问题时,我发现了以下遗留代码:

  1. 将数百个实体加载到内存中
  2. 启用了更改跟踪
  3. 在循环中更新它们
  4. 调用了 SaveChangesAsync()
var cutoff = nowUtc.AddDays(-90);

var users = await db.Users
    .Where(u =>
        u.Status == UserStatus.Active &&
        (u.LastLoginUtc == null || u.LastLoginUtc 
        u.Status == UserStatus.Active &&
        (u.LastLoginUtc == null || u.LastLoginUtc  setters
        .SetProperty(u => u.Status, UserStatus.Archived)
        .SetProperty(u => u.UpdatedAtUtc, nowUtc),
        ct);

根本原因并不是“EF 运行慢”。而是使用了 ORM 抽象却没有理解其代价。

经验教训

  • 了解 LINQ 是如何转换为 SQL 的。
  • 知道何时需要更改跟踪——以及何时不需要。
  • 识别查询何时应采用集合方式、编译方式或直接使用原始 SQL。
  • 为任务选择合适的工具:有时 EF Core 是理想选择;而在其他情况下,存储过程、视图或原始查询可能更合适。

如果你不了解它的工作原理,就不要把问题归咎于工具本身。

Back to Blog

相关文章

阅读更多 »

C# Smart Enums:高级

封面图片:C Smart Enums:advanced https://media2.dev.to/dynamic/image/width=1000,height=420,fit=cover,gravity=auto,format=auto/https%3A%2F%2Fdev-to-upload...

C# 智能枚举:优化版

问题:“LINQ 税” 在第 1 部分中,我们用 records 替换了魔法数字。为了查找特定的状态,我们使用了 LINQ:csharp var status = Status.All.SingleOrDe...