多次调用 SaveChanges() 修改 Dbset/实体

问题描述

我正在开发一个 .NET Core Web API,它需要使用 EF Core 5.0.2 与 Azure sql 数据库进行交互。

我有不同的存储库方法,我与 DbContext 交互以添加/编辑/删除不同 DbSet 的记录。

例如:

UserRepository.AddUser(userdata);

AddUser的实现是这样的,

ourDbContext.UserTable.AddAsync(userdata);

因此在用户服务方法中,我按顺序调用不同的存储库方法,并且这些方法都没有单独调用 ourDbContext.SaveChangesAsync()。在所有存储库方法调用之后出现对 SaveChanges 的单个调用,这对于作为单个事务的所有调用来说就像一个工作单元模式。

示例:

UserRepository.AddUser(userdata);
ActivityRepository.AddActivity("New User got added");
ourDbContext.SaveChangesAsync();

所以我的问题是:如果对任何表/实体的任何保存更改失败,之前成功的表更改是否会回滚?

例如假设这个操作

UserRepository.AddUser(userdata);

成功,新用户记录已添加用户表中。

但这并不成功:

ActivityRepository.AddActivity("New User got added");

因此没有将活动记录添加Activity 表中。

SaveChangesAsync() 能否自动处理这种情况并回滚用户表的新更改?

如果不是我们应该用事务范围包装上面的代码吗?或者推荐的方法是什么。

解决方法

简要说明 DbContext's 变更跟踪器的工作原理:

  • 您加载实体:ChangeTracker 会记住所有加载实体的当前值(除非您使用 AsNoTracking()
  • 您已修改加载的实体、删除、添加新实体。
  • 您调用 SaveChanges:ChangeTracker 通过与之前的值进行比较,开始搜索自上次加载以来发生更改的对象。
  • 生成 DML SQL 并将所有内容保存在一个 SQL 语句或事务中的多个语句中。

因此,如果每个存储库都有一个 DbContext,则无需担心回滚,只需不要调用 SaveChanges()。为确保重启过程,您必须重新创建 DbContext,因为它包含不需要的状态。

相关问答

Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其...
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。...
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbc...