如何解决具有相同键的对象已存在于ObjectStateManager中ObjectStateManager无法使用相同的键跟踪多个对象
:使用原始答案Find
代替Local.SingleOrDefault
。它与@Juan的Save
方法结合使用,但是可能导致对数据库的不必要查询,并且else
部分可能从未执行(执行else部分会导致异常,因为Find已查询数据库并且未找到实体,因此无法更新该实体)
。感谢@BenSwayne找到问题。
您必须检查上下文是否已跟踪具有相同键的实体,并修改该实体而不是附加当前实体:
public override void Update(T entity) where T : IEntity {
if (entity == null) {
throw new ArgumentException("Cannot add a null entity.");
}
var entry = _context.Entry<T>(entity);
if (entry.State == EntityState.Detached) {
var set = _context.Set<T>();
T attachedEntity = set.Local.SingleOrDefault(e => e.Id == entity.Id); // You need to have access to key
if (attachedEntity != null) {
var attachedEntry = _context.Entry(attachedEntity);
attachedEntry.CurrentValues.SetValues(entity);
} else {
entry.State = EntityState.Modified; // This should attach entity
}
}
}
如您所见,主要问题是SingleOrDefault
方法需要知道查找实体的键。您可以创建暴露密钥的简单界面(IEntity
在我的示例中),并在要处理的所有实体中实现它。
解决方法
尝试将EF5与通用存储库模式结合使用,并使用ninject进行依赖关系注入,并在尝试使用带有edmx的存储过程将实体更新到数据库时遇到问题。
我在DbContextRepository.cs中的更新是:
public override void Update(T entity)
{
if (entity == null)
throw new ArgumentException("Cannot add a null entity.");
var entry = _context.Entry<T>(entity);
if (entry.State == EntityState.Detached)
{
_context.Set<T>().Attach(entity);
entry.State = EntityState.Modified;
}
}
从我的AddressService.cs返回到我的存储库,我有:
public int Save(vw_address address)
{
if (address.address_pk == 0)
{
_repo.Insert(address);
}
else
{
_repo.Update(address);
}
_repo.SaveChanges();
return address.address_pk;
}
当它遇到Attach和EntityState.Modified时,它会吐出错误:
具有相同键的对象已存在于ObjectStateManager中。 ObjectStateManager无法使用相同的键跟踪多个对象。
我浏览了堆栈中和Internet上的许多建议,但没有提出任何解决方案。任何变通办法将不胜感激。
谢谢!
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 [email protected] 举报,一经查实,本站将立刻删除。