【问题标题】:How to get rid off "An entity object cannot be referenced by multiple instances of IEntityChangeTracker"?如何摆脱“一个实体对象不能被多个 IEntityChangeTracker 实例引用”?
【发布时间】:2009-03-06 19:23:31
【问题描述】:

我在 Ado.Net EF 中有一个模型。 我有一个一对多的关系,当我想添加实体时出现错误

“一个实体对象不能被多个IEntityChangeTracker实例引用”

有什么线索吗?

类似

Template template = new Template();
...
...
while (from < to)
{
    Course course = new Course();
    .....
    template.Course.Add(course);
    .....
}
courseEntities.AddToTemplate(template); // Problem line
courseEntities.SaveChanges();

【问题讨论】:

    标签: entity-framework


    【解决方案1】:

    在我开始将数据上下文存储在 HttpContext.Items 属性中之前,我收到了这条消息。这意味着您可以对当前的 Web 请求使用相同的数据上下文。这样你就不会得到两个引用相同实体的数据上下文。

    这是DataContext Life Management 上的一篇好帖子。

    希望对你有帮助。

    戴夫

    【讨论】:

      【解决方案2】:

      “模板”,或者它引用的东西,已经被添加到 courseEntities 另一个上下文中。我在您展示的代码中看不到任何内容,但它肯定会发生。也许它发生在您修剪的某些代码中。在调试器中查看“template”的EntityState属性,同时查看“template”属性的EntityState。这应该可以帮助您找出哪个实体实例已经在上下文中。

      【讨论】:

      • "模板,或它引用的东西" - 谢谢克雷格,刚刚解决了 另一个 EF 问题我(也就是说,你现在帮我解决的 10 个 EF 问题?)。此错误不仅会在实体附加到另一个上下文时发生,而且如果此实体引用的 any 对象附加到另一个上下文!
      【解决方案3】:

      我已经意识到问题所在。我有另一个关系,我从另一个上下文中得到另一个实体。

      【讨论】:

        【解决方案4】:

        让我将我的经历与这个令人讨厌的错误联系起来,并指出追逐它的地形会带你去寻找一个非常简单的解决方案。

        CompanyGroup 非常简单。它有一个名称,并且有一个 Company 对象。

        我是从这个开始的:

        1        public static void Add(CompanyGroup item)
        2        {
        3            try
        4            {
        5                using (Entities scope = new Entities())
        6                {
        7             scope.AddToCompanyGroup(item);
        8                       scope.SaveChanges();
        9                }
        10            }
        11            catch (Exception ex)
        12            {
        13                LogException(ex, item);
        14                throw;
        15            }     
        16  }   
        

        得到了这个错误:

        {"实体对象不能 被多个实例引用 IEntityChangeTracker。"}

        所以,我在第 6 行和第 7 行之间添加了这个:

                (IEntityWithChangeTracker)item).SetChangeTracker(null);
        

        这奖励了我:

        {"该对象无法添加到 ObjectStateManager 因为它已经 有一个 EntityKey。采用 ObjectContext.Attach 附加一个 具有现有键的对象。"}

        所以我改变了

        scope.AddToCompanyGroup(item);
        

        scope.Attach(item);
        

        现在它抱怨:

        {"具有临时 EntityKey 的对象 值不能附加到对象 上下文。”}

        (开始听起来像我年轻时约会过的一些女孩——从不满足——但我离题了)

        所以我将实体键设为空(不起作用)并使用该方法创建新的(也不起作用)

        一路上,我也遇到了这个错误:

        {"这个的源查询 EntityCollection 或 EntityReference 相关时无法退换 对象处于添加状态或 一个分离的状态,不是 最初使用 NoTracking 合并选项。"}

        解决方案?

        将核心,第 7 行和第 8 行替换为:

                        CompanyGroup newcg = new CompanyGroup();
                        newcg.GroupName = item.GroupName;
                        newcg.Company = scope.Company.Where(c => c.CompanyID == item.Company.CompanyID).First();
        
              scope.AddToCompanyGroup(newcg);
                        scope.SaveChanges();
        

        本质上,我将通过“item”传递的数据,并将其移动到新创建的引入相同类型的对象中 范围作为添加中使用的范围。

        【讨论】:

          【解决方案5】:

          我希望这是最简单和正确的解决方案。每个 httprequest 需要一个数据库上下文。

          EF4 代码优先模板 Global.asax.cs http://gist.github.com/574505

          void MvcApplication_BeginRequest(object sender, EventArgs e)
          {
           HttpContext.Current.Items[SessionKey] = new Db();
          }
          
          void MvcApplication_EndRequest(object sender, EventArgs e)
          {
           var disposable = HttpContext.Current.Items[SessionKey] as IDisposable;
           if (disposable != null)
            disposable.Dispose();
          }
          

          【讨论】:

            【解决方案6】:

            请仅初始化一次您的实体。

            喜欢

            如果您不止一次初始化您的实体。

            你会得到错误:

            一个实体对象不能被多个 IEntityChangeTracker 实例引用。

            例如:

            public class Test
            
            {
            
             private Entities db=new Entities();
            
             public static void Add(CompanyGroup item)
                {
                    try
                    {
            
                     db.CompanyGroup.Add(item);
                     db.SaveChanges();
            
                    }
                    catch (Exception ex)
                    {
                    }     
                }   
            }
            

            【讨论】:

              【解决方案7】:

              我通过从我更新的对象中删除与其他实体(虚拟)的额外关系来解决这个问题。只留下他们的身份证。

              这是错误的代码

              dataFileEntity.IterParameterValue = parameterValueEntity.ParameterValue;
              dataFileEntity.IterParameterValueId = parameterValueEntity.ParameterValue.Id;
              dataFileEntity.ResultParameter = parameterValueEntity.ResultParameter;
              dataFileEntity.ResultParameterId = parameterValueEntity.ResultParameter.Id;
              dataFileEntity.RawDataResult = result.Value;
              

              这是对的

              dataFileEntity.IterParameterValueId = parameterValueEntity.ParameterValue.Id;
              dataFileEntity.ResultParameterId = parameterValueEntity.ResultParameter.Id;
              dataFileEntity.RawDataResult = result.Value;
              RequestTestRawDataFileRepository.AddOrUpdate(dataFileEntity);
              

              Я эту проблему решила, убрав из объекта, который я апдейтила лишние связи с другими сущностями(虚拟)。 Оставила только их id.

              【讨论】:

              • 自动翻译器告诉我最后一段是“我已经解决了这个问题,由于其他实体(虚拟),从我更新的对象中删除是不必要的。只留下他们的身份证。'
              猜你喜欢
              • 2011-11-01
              • 2011-10-12
              • 1970-01-01
              相关资源
              最近更新 更多