Web API:与IEntityChangeTracker的多个实例的EF6问题

时间:2014-11-11 02:07:23

标签: asp.net-mvc entity-framework ef-code-first entity-framework-6 dbcontext

我的Web API应用程序中出现以下错误。

“IEntityChangeTracker的多个实例无法引用实体对象”

步骤1:浏览器将已修改的版本发布到API控制器,后者又调用服务上的更新。

ReleaseController.cs

public Guid Update(EditReleaseViewModel release)
    {
        if (!ModelState.IsValid) throw new Exception("Invalid model");

        var updatedRelease = _releaseService.Update(release);
        return updatedRelease.ID;
    }

第2步:服务检索并修改版本。 (该服务使用Ninject获取每个请求注入的DbContext)

ReleaseService.cs

public Release Update(EditReleaseViewModel release)
    {
        var existingRelease = _context.Releases.Single(x => x.ID == release.ID);

        existingRelease.Name = release.Name;
        existingRelease.CatalogNumber = release.CatalogNumber;

        _context.Entry(existingRelease).State = EntityState.Modified; // ERROR HAPPENS HERE!
        _context.SaveChanges();

        return existingRelease;
    }

我读到当一个实体仍在内存中时会发生这种情况(在处理前一个DbContext之前没有分离)。

问题是我在尝试在同一服务中再次更新它之前使用相同的服务来检索版本吗?

如果是的话,最好的解决方法是什么?谢谢!

1 个答案:

答案 0 :(得分:2)

当您从dbcontext检索existingRelease时,其中一个好处是您的上下文已经附加,并且您的状态跟踪是免费提供的。您需要做的就是更新您的名字/ catalognumber并调用SaveChanges。

public Release Update(EditReleaseViewModel release)
{
    var existingRelease = _context.Releases.Single(x => x.ID == release.ID);

    existingRelease.Name = release.Name;
    existingRelease.CatalogNumber = release.CatalogNumber;

    _context.SaveChanges();

    return existingRelease;
}

手动设置实体的状态时如下:

_context.Entry(existingRelease).State = EntityState.Modified;

这里发生了两件事:1)它试图将existingRelease附加到_context(由于它已经从检索中附加到它而在此失败)和2)将所有属性标记为已修改 - 而不仅仅是2你已经更新了。

希望有所帮助。