.net 保存来自不同线程的更改时的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

我有一个EF代码首先生成的数据库。使用
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()时时,事件集合似乎会被较旧的事件集合覆盖,从而使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
,修复了该问题。

是。我已经在问题正文中写了一篇更新文章,因为我发现,我向问题读者提供了关于问题设置的错误信息。请看一看。