在尝试附加实体时,我在尝试更新时收到“已存在具有相同密钥的对象”。延迟加载已打开。我用谷歌搜索,并没有发现这个问题的真正解决方案。我最好的解决方案是替换对象状态管理器中的条目,但我无法在任何地方找到如何替换它。有可能吗?
当我在一个上下文中创建对象 A 的实例(具有对象 B 的集合)并在另一个上下文中创建 B 对象时,就会出现问题。当我尝试将它们都连接起来时,它会破裂。有没有办法告诉 EF 何时替换它正在跟踪的条目。当我将重复的实体键条目对象状态设置为已修改时,它是否可能允许替换。
在尝试附加实体时,我在尝试更新时收到“已存在具有相同密钥的对象”。延迟加载已打开。我用谷歌搜索,并没有发现这个问题的真正解决方案。我最好的解决方案是替换对象状态管理器中的条目,但我无法在任何地方找到如何替换它。有可能吗?
当我在一个上下文中创建对象 A 的实例(具有对象 B 的集合)并在另一个上下文中创建 B 对象时,就会出现问题。当我尝试将它们都连接起来时,它会破裂。有没有办法告诉 EF 何时替换它正在跟踪的条目。当我将重复的实体键条目对象状态设置为已修改时,它是否可能允许替换。
你的问题有两个部分。
1. 检测一个实体是否已经被上下文跟踪。
如果您有两个对同一实体实例的引用,则很容易查看它是否正在被跟踪。
Boolean isTracked = context.MyEntities.Local.Contains(myEntity);
相反,如果您有两个概念上相同的实体实例,因为它们具有相同的键,那么事情可能会更加困难。
Boolean isTracked = context.MyEntities.Local.Any(x=>x.Id == myEntity.Id);
或者使用EqualityComparer<T>
:
public class MyEntityEqualityComparer : EqualityComparer<MyEntity>
{
public override bool Equals(MyEntity x, MyEntity y)
{
return x.Id == y.Id;
}
public override int GetHashCode(MyEntity obj)
{
return obj.Id;
}
}
context.MyEntities.Local.Contains(myEntity, new MyEntityEqualityComparer());
2. 关闭被跟踪的实体。
这可以像这样实现:
context.Entry<MyEntity>(entityToReplace).State = EntityState.Detached;
context.MyEntities.Attach(entityToAdd);
然而,在你做这一切之前,你应该看看你的应用程序设计。必须在上下文之间处理实体可能表明您没有将任务分组到可以在单个上下文中操作的适当工作单元中。