我有一个应用程序需要以每小时的间隔同步内存数据和远程数据库。因此,在应用程序启动时数据将从数据库中提取,并且DbContext将被丢弃。
List<Department> Departments;
using (var context = new CompanyContext())
{
this.Departments = context.Departments.Include("Employees").AsNoTracking().ToList();
}
另一个线程在一小时后启动同步功能。我可以确认 HAVE 是对[this.Departments]
集合所做的更改(由所有线程共享)。
bool changesDetectedAndSaved = false;
using (var context = new CompanyContext())
{
foreach (var department in this.Departments)
{
foreach (var employee in department.Employees)
{
context.Departments.Attach(employee);
}
context.Departments.Attach(departments);
}
// Always returns false.
context.ChangeTracker.DetectChanges();
changesDetectedAndSaved = context.ChangeTracker.HasChanges());
if (changesDetectedAndSaved) { context.SaveChanges(); }
}
Console.WriteLine("Saved: {0}.", changesDetectedAndSaved);
[context.ChangeTracker.HasChanges()]
方法始终返回false。由于数据库是远程的,所以不可能长时间保持DbContext
活着。是不是DbSet<TEntity>.Attach(entity)
应该处理这种事情?
请注意:这不是一个线程问题,因为当代码放入here这样的单个上下文时,我会得到相同的结果。
答案 0 :(得分:2)
在此期间内没有DbContext
跟踪更改;将实体附加到DbContext
是指示DbContext
实例跟踪所述实体。当您将实体对象附加到新DbContext
时,它会附加为Unchanged
,当您致电SaveChanges()
时,它不会发生任何事情。
要在数据库中更新实体,必须将其状态设置为Modified
。附加和设置状态的最简单方法如下:
context.Entry( employee ).State = EntityState.Modified;
在实体框架5之前,有自我跟踪实体(which are still available for use)的T4模板,其中实体对象本身可以跟踪其状态,但不再推荐使用这些实体。