Ido*_*dov 7 c# asp.net-mvc multithreading entity-framework
我需要在单个事务中更新我的数据库中的几个表,并且我认为使用DbContext.SaveChanges应该是这样做的方法.
但是我还读到,它的生命周期DbContext应该尽可能短,因为它会随着时间的推移而增加,因为它会加载更多的实体.
我还读到,为了使其成为线程安全的,每个动作都应该有自己的DbContext.
我应该有一个DbContext,因为我想改变,并呼吁每个表SaveChanges上的每一个DbContext?最后一次SaveChanges通话是否会覆盖之前通话的更改?
最好的方法是什么?(我需要这个网站)
简单的方法是,为了每个请求有一个 DbContext,ASP.NET MVC 实现了所有线程安全,ASP.NET MVC 中的每个控制器实例对于每个请求都是隔离的,您不必担心竞争条件。只要您不创建线程,而只是使用单个 DbContext 在操作方法中进行数据转换,就不会有任何问题。
基本上DbContext什么都不做,它只是将SQL查询排队到目标数据库,它是处理多线程、竞争条件的数据库。为了保护您的数据,您应该使用事务并在数据库中添加验证以确保它们正确保存
public abstract class DbContextController : Controller{
public AppDbContext DB { get; private set;}
public DbContextController(){
DB = new AppDbContext();
}
protected override void OnDisposing(bool disposing){
DB.Dispose();
}
}
Run Code Online (Sandbox Code Playgroud)
如果您从控制器继承任何类DbContextController并在控制器的整个生命周期中使用数据库,则不会有任何问题。
public ActionResult ProcessProducts(){
foreach(var p in DB.Products){
p.Processed = true;
foreach(var order in p.Orders){
order.Processed = true;
}
}
DB.SaveChanges();
}
Run Code Online (Sandbox Code Playgroud)
但是,如果您使用任何线程,如下例所示,
public ActionResult ProcessProducts(){
Parallel.ForEach(DB.Products, p=>{
p.Processed = true;
// this fails, as p.Orders query is fired
// from same DbContext in multiple threads
foreach(var order in p.Orders){
order.Processed = true;
}
});
DB.SaveChanges();
}
Run Code Online (Sandbox Code Playgroud)