处置DBContext,然后使用EF6将实体附加到新实例

时间:2013-11-30 13:01:58

标签: c# .net entity-framework

我有一个应用程序需要以每小时的间隔同步内存数据和远程数据库。因此,在应用程序启动时数据将从数据库中提取,并且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这样的单个上下文时,我会得到相同的结果。

1 个答案:

答案 0 :(得分:2)

在此期间内没有DbContext跟踪更改;将实体附加到DbContext是指示DbContext实例跟踪所述实体。当您将实体对象附加到新DbContext时,它会附加为Unchanged,当您致电SaveChanges()时,它不会发生任何事情。

要在数据库中更新实体,必须将其状态设置为Modified。附加和设置状态的最简单方法如下:

context.Entry( employee ).State = EntityState.Modified;

Read this

在实体框架5之前,有自我跟踪实体(which are still available for use)的T4模板,其中实体对象本身可以跟踪其状态,但不再推荐使用这些实体。