EF Core SaveChanges怎么用 EF Core SaveChanges方法详解

SaveChanges 是 EF Core 将内存中增删改操作持久化到数据库的核心方法,它基于变更追踪自动识别状态、生成 SQL、启用事务并确保原子性。

EF Core 的 SaveChanges 是把内存中对实体的增删改操作真正写入数据库的“最后一道指令”。它不是简单地执行 SQL,而是基于变更追踪(Change Tracking)自动识别哪些实体变了、怎么变的,再生成并执行对应命令。用对了,省心又安全;用错了,可能数据不一致、事务失效,甚至漏保存。

SaveChanges 做了什么

调用它时,EF Core 会按顺序完成三件事:

  • 扫描 DbContext 中所有被跟踪的实体,检查它们的状态(Added / Modified / Deleted)
  • 根据状态生成一条或多条 SQL 命令(INSERT / UPDATE / DELETE),必要时自动处理主键回填(比如自增 ID)、外键关联(如先插 Blog 再插 Post)
  • 在数据库连接上启动一个事务(默认开启),执行全部命令;任一失败则整体回滚,确保原子性

基本用法就这几种

不需要手动拼 SQL,也不用管事务开关(除非你明确要关):

  • 新增:用 Add()AddRange() 加入实

    体,再调 SaveChanges()
  • 修改:从查询加载实体后直接改属性值(如 blog.Title = "新标题"),EF 自动标记为 Modified
  • 删除:用 Remove()RemoveRange(),或设 Entry(e).State = EntityState.Deleted
  • 混合操作:一次 Add + 一次 Modify + 一次 Remove,全在同一个 SaveChanges() 中提交,天然事务保障

事务控制的关键细节

默认情况下,每个 SaveChanges() 都自带事务——但仅限本次调用内所有操作。跨多次调用必须手动管事务:

  • 单次 SaveChanges:自动事务,无需干预。例如批量插入 10 条客户记录,失败则全不入库
  • 多次 SaveChanges:比如先加 Product,再用它的 ID 加 Order,这时得用 BeginTransaction() 包住两次 SaveChanges,否则第二次失败会导致 Product 白存了
  • 想关掉默认事务?可以设 context.Database.AutoTransactionsEnabled = false,但极少需要,关了就失去原子保障

异步和性能注意点

高并发或耗时操作建议用异步版本:

  • SaveChangesAsync() 是推荐做法,避免线程阻塞,尤其 Web 应用
  • EF Core 会自动批处理同类型命令(比如连续 5 个 INSERT),减少数据库往返,提升性能
  • 别在循环里反复调 SaveChanges —— 每次都开事务、建连接、发命令,效率低。应先 AddRange,最后统一 SaveChanges

基本上就这些。核心就一条:让 EF 跟踪你的实体,它自然知道该做什么;你只管业务逻辑,事务和 SQL 交给它兜底。