ObjectStateManager.TryGetObjectStateEntry对于附加对象返回false [英] ObjectStateManager.TryGetObjectStateEntry returns false for attached object
问题描述
TryGetObjectStateEntry返回false,但是当我尝试附加实体时,我得到'ObjectStateManager中已经存在具有相同键的对象。 ObjectStateManager无法跟踪具有相同键的多个对象。
TryGetObjectStateEntry returns false but when i try to attach the entity i get 'An object with the same key already exists in the ObjectStateManager. The ObjectStateManager cannot track multiple objects with the same key.'
实体键的类型为Guid。
The entity key is of type Guid.
这怎么可能?
编辑:我附加了两个不同键的实体。该错误总是发生在我附加的这种类型的第二个实体上。如果我交换它们,错误仍然在第二个。
i am attaching 2 entities with different key. the error occurs always on the second entity of this type that i attach. if i swap them the error is still on the 2nd one.
public bool IsAttached<T>(T obj) where T : class
{
ObjectStateEntry entry = null;
ObjectContext objCtx = GetObjectContext();
bool isKeyAttached = false;
EntityContainer container = objCtx.MetadataWorkspace.GetEntityContainer(objCtx.DefaultContainerName, DataSpace.CSpace);
EntitySetBase entitySet = container.BaseEntitySets.Where(item => item.ElementType.Name.Equals(typeof(T).Name)).FirstOrDefault();
System.Data.EntityKey key = objCtx.CreateEntityKey(entitySet.Name, obj);
if (objCtx.ObjectStateManager.TryGetObjectStateEntry(key, out entry))
{
isKeyAttached = entry.State != System.Data.EntityState.Detached;
}
return isKeyAttached;
}
推荐答案
您附加的实体具有引用其他实体的导航属性。示例:
This problem can occur if the entities you attach have navigation properties refering to other entities. Example:
public class Parent
{
public int Id { get; set; }
public Child Child { get; set; }
}
public class Child
{
public int Id { get; set; }
}
以下代码将抛出异常:
using (var context = new MyDbContext())
{
var parent = new Parent { Id = 1 };
var child1 = new Child { Id = 1 };
parent.Child = child1;
var child2 = new Child { Id = 1 }; // same key
context.Children.Attach(child2); // child with key = 1 is attached now
var objContext = ((IObjectContextAdapter)context).ObjectContext;
ObjectStateEntry entry;
bool isAttached = objContext.ObjectStateManager.TryGetObjectStateEntry(
new EntityKey("MyDbContext.Parents", "Id", parent.Id), out entry);
// isAttached will be false because a Parent with Id = 1 is not attached
if (!isAttached)
{
// we assume now that we could attach the parent safely
context.Parents.Attach(parent);
// Assumption is wrong -> Exception, because Attach attaches the whole
// object graph, so it tries also to attach child1 together with parent
// But child1 has the same key as child2 which is already attached
}
}
所以,关键是 TryGetObjectStateEntry
只检查基本实体的状态,不考虑导航属性。另一方面,附加
不仅附加基础实体,而且附加尚未附加的子代,导致异常。
So, the point is that TryGetObjectStateEntry
only checks the state of the base entity and doesn't consider any navigation properties. Attach
on the other hand does not only attach the base entity but also the children which are not yet attached, leading to the exception.
这篇关于ObjectStateManager.TryGetObjectStateEntry对于附加对象返回false的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!