c# - 隔离 EF Core 中的更改
问题描述
以下是我DbContext
在 ASP.NET Core Startup 中添加服务的方法:
services.AddDbContextPool<AppDbContext>(options =>
options.UseMySql(Configuration.GetConnectionString("DefaultConnection")));
services.AddScoped<ClassA, ClassA>();
services.AddScoped<ClassB, ClassB>();
A 类 - 方法 1
_dbContext.EntityX.Add(new EntityX { ... });
var product = ClassB.GetProduct(key);
_dbContext.EntityY.Add(new EntityY { Product = product });
_dbContext.SaveChanges();
B 类 - 获取产品
//Check product if it exists in the database
//Else, get details of the product from a Web API
var newProduct = new Product{ ... }
_dbContext.Products.Add(newProduct );
_dbContext.SaveChanges();
return newProduct;
老实说,我还没有尝试过运行它,为了简洁起见,这些代码被(大量)剥离了真实代码的版本。
我的问题是:
1)我DbContext
在两者中ClassA
是否相同ClassB
?这有保证吗?
2)如果两者ClassA
和ClassB
相同DbContext
,SaveChanges
inClassB
会影响EntityX
我添加的 inClassA
吗?
3) 我应该怎么做才能隔离ClassA
和的变化ClassB
?
解决方案
我在和
DbContext
中都一样吗?这有保证吗?ClassA
ClassB
数据库上下文被注册为范围依赖,这意味着在处理单个传入请求期间共享实例。每个请求都将获得自己的依赖注入范围,因此在单个请求中,您可以保证获得相同的数据库上下文实例。
另一方面,您也可以保证为单独的请求获取单独的数据库上下文。
如果两者
ClassA
都ClassB
相同DbContext
,那么SaveChanges
inClassB
会影响EntityX
我添加的ClassA
吗?
对此的简短回答是肯定的。由于它是一个单一的数据库上下文,因此还有一个正在跟踪的实体集合。因此,如果您ClassA.Method1
先运行并且那里没有SaveChanges
调用,然后运行ClassB.Method2
,SaveChanges()
则后者中的也将保存第一种方法的更改。
虽然这听起来可能有问题,但实际上通常不会:请求通常作为控制器操作的一部分进行处理,因此有一个非常清晰的控制流。因此,没有任何并行处理,只要你在使用它后总是“清理”上下文(例如通过调用SaveChanges()
)就没有问题。
另一方面,您也可以利用它来发挥自己的优势,并在整个请求处理过程中共享事务,而您的方法并不知道它们是事务的一部分。
我应该怎么做才能隔离
ClassA
和的变化ClassB
?
想想你是否真的需要隔离。Method2
您可能影响的唯一方法Method1
是Method1
对未保存的实体执行更改。如果你这样做,那么你很可能会滥用你的实体。通常,一个方法应该在不留下脏状态的情况下完成它对实体的工作。
推荐阅读
- forms - AEM Forms 将 JEE 升级到 OSGI
- python - 如何在python中使用多个索引同时填充numpy数组
- c# - mysql权限错误。涉及 SELECT 命令
- firebase - Firestore 不断写文件
- matlab - 如何从 3D 数组的选定列构造矩阵?
- android - ViewModel 在同一个 Activity 中跨 Fragment 的作用域
- python - 来自 Automate the Boring Stuff 的示例程序未按描述工作
- c++ - 如何用字符串管道?
- javascript - Webview Javascript 在 Android 7.0 及更高版本中不起作用
- javascript - 如何将选定的值呈现到多下拉框中