.net 保存来自不同线程的更改时的EF一致性跟踪
我有一个EF代码首先生成的数据库。使用.net 保存来自不同线程的更改时的EF一致性跟踪,.net,entity-framework,concurrency,dbcontext,.net,Entity Framework,Concurrency,Dbcontext,我有一个EF代码首先生成的数据库。使用DbContext完成数据操作。Asp.net应用程序中的IoC容器生成一个DbContext实例,BL对象基于每个线程依赖该实例。是与web应用程序一起加载的后台任务类 每隔一段时间(如每10分钟),后台线程通过调用事务范围内的myDbContext.Add向事件列表添加一项 同时,如果“web请求线程”中的一个事件被myDbContext更改,则即使这些更改被保存到数据库中一段时间,它们也会被事件集覆盖,在用户使用web页面更改事件之前的几分钟,由bac
DbContext
完成数据操作。Asp.net应用程序中的IoC容器生成一个DbContext
实例,BL对象基于每个线程依赖该实例。是与web应用程序一起加载的后台任务类
每隔一段时间(如每10分钟),后台线程通过调用事务范围内的myDbContext.Add
向事件列表添加一项
同时,如果“web请求线程”中的一个事件被myDbContext
更改,则即使这些更改被保存到数据库中一段时间,它们也会被事件集覆盖,在用户使用web页面更改事件之前的几分钟,由backgound线程拉取的
这似乎是一个并发性问题(我没有实现任何类似时间戳列的并发性)
我的问题是:后台线程不应该只保存更改的数据(在我的例子中,添加一个新事件),而保留整个事件集合吗?如果这是真的,我的问题来源是其他地方
来自后台线程的代码:
using (var transaction = new TransactionScope())
{
foreach (var scheduledTask in _db.ScheduledTasks)
{
if (scheduledTask.NextExecuteAfterDate == null)
{
PopulateNextExecuteAfterDate(scheduledTask);
shouldSaveChanges = true;
}
if (DateTime.Now > scheduledTask.NextExecuteAfterDate)
{
RegisterRecurringTicket(scheduledTask);
CalculateNextTime(scheduledTask);
shouldSaveChanges = true;
}
}
if (shouldSaveChanges) _db.SaveChanges();
transaction.Complete();
}
子例程<代码>RegisterRecurringTicket(scheduledTask)中的代码代码>将项目添加到事件集合。当a\u db.SaveChanges()时调用code>时,事件集合似乎会被较旧的事件集合覆盖,从而使UI生成的对事件集合的更改过时。如果是,如何解决此问题?只需调用myDbContext.incents.ToList()
不会导致数据库中的任何内容被覆盖。然而,我可以很容易地想象这样的情况:
// My Incident tracker
IEnumerable<Incident> CurrentIncidents {get{return myDbContext.Incidents.ToList();}}
// Meanwhile, in another class on the same thread...
foreach(var incident in IncidentTracker.CurrentIncidents)
{
var claims = myDbContext.Claims.Where(c => c.IncidentId == incident.IncidentId);
foreach(var claim in claims)
{
Process(claim);
}
incident.Processed = true;
}
myDbContext.SaveChanges();
//我的事件跟踪器
IEnumerable CurrentEvents{get{return myDbContext.Events.ToList();}
//同时,在同一线程上的另一个类中。。。
foreach(IncidentTracker.CurrentIncidents中的var事件)
{
var claims=myDbContext.claims.Where(c=>c.IncidentId==incidention.IncidentId);
foreach(索赔中的var索赔)
{
过程(索赔);
}
事件处理=真;
}
myDbContext.SaveChanges();
在上面的示例中,尽管您没有直接从myDbContext
中提取事件
,但由于两个类都注入了相同的上下文,因此调用SaveChanges()
实际上会影响声明(您想要更改)和事件(您没有更改)
有没有可能发生类似的情况?问题是我使用了PerThreadScope
DbContext
注入。这导致我的ASP.NET应用程序出现意外行为。在PerRequestScope
中将Ninject模块设置为解析DbContext
,修复了该问题。是。我已经在问题正文中写了一篇更新文章,因为我发现,我向问题读者提供了关于问题设置的错误信息。请看一看。