【问题标题】:Entity framework's invalid operation exception "An entity object cannot be referenced by multiple instances of IEntityChangeTracker"实体框架的无效操作异常“一个实体对象不能被多个IEntityChangeTracker实例引用”
【发布时间】:2013-12-25 17:08:47
【问题描述】:

我在实体框架 6 中遇到了一个相当令人困惑的“一个实体对象不能被多个 IEntityChangeTracker 实例引用”错误,虽然通过实施一个简单的解决方法很容易解决这个问题,但关键是原来的实施应该按原样工作。这是相关类的外观

public class Response
{
    public int Id { get; set; }

    public string QuestionId { get; set; } 
//foreign key
    public int UserId { get; set; }
    public virtual User User { get; set; }

    public bool IsDeleted { get; set; }
}

public class User
{
    public int Id { get; set; }

    public string UserName {get; set;}
    public virtual List<Response> Responses { get; set; }

    public bool IsDeleted { get; set; }
}

并且,更新响应的相关代码如下

/* 1 */ using (var db = new SomeContext())
/* 2 */ {
/* 3 */       var existingResponses = userResponses.Select(userResponse =>
/* 3 */                db.Responses.FirstOrDefault(
/* 3 */                r => r.QuestionId.Equals("1.1.1") 
/* 3 */                && r.User.Id.Equals(user.Id) && !r.IsDeleted))
/* 3 */                .Where(existingResponse => existingResponse != null).ToList();
/* 4 */       if (existingResponses.Any())
/* 5 */       {
/* 6 */            foreach (var response in existingResponses)
/* 7 */            {
/* 8 */                 response.IsDeleted = true;
/* 9 */            }
/* 10 */       }

/* 11 */     var newResponses = new List<Response>()
/* 12 */     {
/* 13 */         new Response()
/* 14 */         {
/* 15 */            QuestionId = "1.1.1",
/* 16 */            User = user,
/* 17 */            //UserId = user.Id,
/* 18 */          }
/* 19 */     };

/* 20 */     newResponses.ForEach(r => db.Responses.Add(r));

/* 21 */      db.SaveChanges();

上面的代码很简单;我首先更新现有记录并将其 IsDeleted 设置为 true,然后添加新记录,在此特定示例中,首先更新带有 QuestionId == "1.1.1" 的响应记录,然后更新带有 QuestionId == " 的新响应记录1.1.1" 已插入。如果我注释掉第 16 行并取消注释第 17 行,那么一切正常,但是如上所示执行代码的那一刻,我得到一个“无效操作异常”一个实体对象不能被多个 IEntityChangeTracker 实例引用”。用户存在于用户表,并按原样检索

var user = _db.Users.FirstOrDefault(r => r.UserName.Equals("someUserName@someDomain.com"));

我查看了有关 stackoverflow herehere 的一些相关问题,尽管解决方法有效,但我的问题是,这肯定是 EF6 本身的错误。我不应该为 Ids 而烦恼,并且应该能够根据上面的第 16 行简单地分配一个对象,这就是 ORM 的全部目的。

而且,作为一个推论,如果这是一个错误,那么我是否应该始终采用使用第 17 行代码的路线?

【问题讨论】:

  • 似乎“用户”对象是从另一个 DBContext 实例中检索的。然后你试图将它链接到这个 DBContext 实例。每个实体只能属于一个 DBContext 实例。
  • 如果您将加载此用户的代码移动到具有相同 DBContext 实例的相同 using 块中,那么它应该可以正常工作
  • @SergeyLitvinov:根据您的评论做出回答,因为它是正确的答案。

标签: c# entity-framework


【解决方案1】:

每个实体都有指向用于创建它的 DBContext 的链接。并且一个 DBContext 中的实体不能与另一个 DBContext 一起使用,因此您需要将其与原始 DBContext 分离并附加到新的 DBContext,或者使用相同的 DBContext。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-11-01
    • 2011-10-12
    • 1970-01-01
    相关资源
    最近更新 更多