ObjectStateManager.TryGetObjectStateEntry对于附加对象返回false [英] ObjectStateManager.TryGetObjectStateEntry returns false for attached object

查看:300
本文介绍了ObjectStateManager.TryGetObjectStateEntry对于附加对象返回false的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆