【发布时间】:2015-12-15 14:21:19
【问题描述】:
我有这个控制器动作:
[HttpGet]
[Route("api/person/test/{id}")]
public IHttpActionResult Test(Guid id)
{
var person = this.PersonManager.Get(id);
person.Lastname = "Jameson";
this.PersonManager.Save(person);
return Ok(true);
}
在这个保存方法的深处调用:
protected void Add<T>(T source, MyEntities context, bool isNew) where T : class
{
if (isNew)
{
context.Set<T>().Add(source);
}
else
{
var entry = context.Entry(source);
if (entry.State == EntityState.Detached)
{
context.Set<T>().Attach(source);
entry.State = EntityState.Modified;
}
}
}
执行此操作时出现此错误:
附加类型为“Model.Person”的实体失败,因为另一个 相同类型的实体已经具有相同的主键值。这个 使用“附加”方法或设置状态时可能发生 如果图中的任何实体具有,则实体为“未更改”或“已修改” 键值冲突。这可能是因为一些实体是新的并且 尚未收到数据库生成的键值。在这种情况下使用 'Add' 方法或 'Added' 实体状态来跟踪图形和 然后将非新实体的状态设置为“未更改”或“已修改”为 合适。
它出现在context.Set<T>().Attach(source) 行。
PS:这是question 的后续/衍生。
【问题讨论】:
-
如果您使用 Get 加载它,为什么在这种情况下您的实体会分离?看起来它已加载并保存在 DbContext 中,因此当您再次附加它时,它与自身的原始副本冲突。您还处理 Get 和 Save 操作之间的上下文吗?
-
@raderick:好问题。这是一个后续问题,是关于意外的 Dispose。这可能是导致此问题的原因。
-
您绝对应该跟踪您的人员实体从加载到再次保存的实体状态,看起来在某些时候它已分离但也保持在相同的上下文中,所以当您再次附加它时会发生此问题。
-
您能否检查
context.person.Local以查看是否有一个人对象与更新的人对象具有相同的主对象?
标签: c# .net asp.net-mvc entity-framework