0

在我的存储库更新方法中,我首先附加现有对象,这些对象可能需要在执行任何其他操作之前添加到更新实体的集合中,以便 EF 意识到我想将该实体与另一个现有实体相关联,而不是创建一个新实体。所以在这个例子中,我正在使用用户组:

UserGroup basicGroup = repoGroup.GetGroupByName("BasicGroup");
List<UserGroup> updatedGroups = new List<UserGroup> { basicGroup };
foreach (var user in usersToUpdate) {
    repoUser.UpdateUser(user.userId, updatedGroups);
}

[...]

public bool UpdateUser(int updatedUserId, List<UserGroup> updatedGroups) {
    using (var context = new MyDbContext()) {
        if (updatedGroups != null) {
            // Attach groups to context before add so that EF creates a new
            // relationship between entity and new items in groups collection,
            // instead of creating a new entity for each new item.
            foreach (UserGroup group in updatedGroups) {

                var testEntry = context.Entry(group);

                context.UserGroups.Attach(group);
            }
        }

        var userToUpdate = context.Users.First(usr => usr.id == updatedUserId);
        userToUpdate.UserGroups.Clear();
        foreach (var group in updatedGroups) {
            userToUpdate.UserGroups.Add(group);
        }

        context.SaveChanges();
        return true;
    }
}

因此,我的代码在几个用户之间循环,并尝试将一组新的组与他们关联起来。我意识到我在这里犯的错误是我.Attach可能试图将同一个实体两次附加到对象上下文 - 在这种情况下,basicGroup. 所以我想我可以测试一下对象是否已经被附加,如果没有附加它。

所以看看 testEntry 行。在那里,我尝试获取group实体的Entry状态。我确实得到了一个DbEntityEntry实例,但它总是说EntityStateDetached(在每个循环迭代中)。现在,当我运行我的代码时,在 foreach 循环的第一次迭代中没问题,但在第二次迭代中,我得到了异常:

ObjectStateManager 中已存在具有相同键的对象。ObjectStateManager 无法跟踪具有相同键的多个对象。

我不明白这一点;如果对象已经存在于 ObjectStateManager 中,为什么我DbEntityEntry说它的状态是Detached?它当然应该记住它的状态是Unchanged

4

1 回答 1

0

不久前我遇到了这个问题,基本上是编译器告诉你,在你的上下文中,你有一个实体加载到内存中,然后你试图将它附加回相同的上下文(第二次 forloop 迭代 -附加的对象位于该初始上下文中)。

要解决此问题,对于 .Add 方法,请使用单独的上下文(新的“使用”调用),这将起作用。这是我能找到的唯一解决方法。

即(我的 UnitOfWork = 你的正常上下文)

UnitOfWork _context = new UnitOfWork();

// Add 1
_context.Add(obj);

using(UnitOfWork context = new UnitOfWork()){
   // Do second addition routines here based on objects used in add 1.
   context.Add(childobj);
   context.SaveChanges();
}

_context.SaveChanges();
于 2013-02-19T12:06:10.410 回答