【问题标题】:EF Code First IDbSet<TEntity>.Attach() Conflicting changes to the role _ of the relationship _ have been detectedEF 代码优先 IDbSet<TEntity>.Attach() 已检测到对关系 _ 的角色 _ 的冲突更改
【发布时间】:2012-11-01 09:32:36
【问题描述】:

我有以下代码:

using (var db = new SourceLogContext())
{
    db.LogEntries.Attach(this);
    db.Entry(this).Collection(c => c.ChangedFiles).Load();
}

我得到以下异常:

System.InvalidOperationException occurred
  Message=Conflicting changes to the role 'LogEntry_LogSubscription_Target' of the relationship 'SourceLog.Model.LogEntry_LogSubscription' have been detected.
  Source=System.Data.Entity
  StackTrace:
       at System.Data.Objects.DataClasses.RelatedEnd.IncludeEntity(IEntityWrapper wrappedEntity, Boolean addRelationshipAsUnchanged, Boolean doAttach)
       at System.Data.Objects.DataClasses.EntityCollection`1.Include(Boolean addRelationshipAsUnchanged, Boolean doAttach)
       at System.Data.Objects.DataClasses.RelatedEnd.WalkObjectGraphToIncludeAllRelatedEntities(IEntityWrapper wrappedEntity, Boolean addRelationshipAsUnchanged, Boolean doAttach)
       at System.Data.Objects.DataClasses.RelatedEnd.AddGraphToObjectStateManager(IEntityWrapper wrappedEntity, Boolean relationshipAlreadyExists, Boolean addRelationshipAsUnchanged, Boolean doAttach)
       at System.Data.Objects.DataClasses.RelatedEnd.IncludeEntity(IEntityWrapper wrappedEntity, Boolean addRelationshipAsUnchanged, Boolean doAttach)
       at System.Data.Objects.DataClasses.EntityReference`1.Include(Boolean addRelationshipAsUnchanged, Boolean doAttach)
       at System.Data.Objects.DataClasses.RelationshipManager.AddRelatedEntitiesToObjectStateManager(Boolean doAttach)
       at System.Data.Objects.ObjectContext.AttachTo(String entitySetName, Object entity)
       at System.Data.Entity.Internal.Linq.InternalSet`1.<>c__DisplayClass2.<Attach>b__1()
       at System.Data.Entity.Internal.Linq.InternalSet`1.ActOnSet(Action action, EntityState newState, Object entity, String methodName)
       at System.Data.Entity.Internal.Linq.InternalSet`1.Attach(Object entity)
       at System.Data.Entity.DbSet`1.Attach(TEntity entity)
       at SourceLog.Model.LogEntry.LoadChangedFiles() in C:\github.com\tomhunter-gh\SourceLog\SourceLog.Model\LogEntry.cs:line 62
  InnerException: (empty)

违规行在这里:https://github.com/tomhunter-gh/SourceLog/blob/443fb74a37db89522f85b4dfc941c52922785e7a/SourceLog.Model/LogEntry.cs#L62

LogEntry 在此处分配了 LogSubscription:https://github.com/tomhunter-gh/SourceLog/blob/443fb74a37db89522f85b4dfc941c52922785e7a/SourceLog.Model/LogSubscription.cs#L88

看起来该分配创建了一个新的 LogSubscription 实例并对其进行分配,然后 Attach 引用了一个不同的实例(但具有相同的 Id)。为什么这会导致错误,我该如何避免?

在 LogSubscription L88 中,我基本上是在尝试将 LogEntry 添加到 LogSubscription 的集合属性中,但没有加载整个 LogEntry 集合。这是正确的做法吗?

【问题讨论】:

  • 是不是类似于this
  • 是的,就是这样(至少是同样的错误信息)。我已经看过那个帖子,但不幸的是它并没有帮助我找出我的问题。我认为发生的事情是 LogEntry 被分配给一个 LogSubscription 实例,然后添加到一个可观察的集合中,该集合以某种方式将 LogSubscription 引用更新到另一个实例(持有 LogEntry 集合的那个),当我尝试时 EF 检测到这一点重新附加 LogEntry..
  • 看到你的代码,也是在你之前的问题之后,我再次觉得你应该重新考虑你的架构。代码优先的目的是持久性无知。您通过在实体对象中使用持久性代码(即上下文)来破坏该目的。这真的很臭。我可以想象它会引起各种副作用。例如:LogEntry 对象由上下文具体化。对象将自身附加到另一个上下文。那时它是否总是脱离其原始上下文?使用实现INotifyPropertyChanged 的视图模型。你的课太忙了。
  • 感谢@GertArnold 的反馈。我绝对可以指导重新架构和模式。你知道我可以看的任何好的文章/书籍吗?我见过不少 ASP.NET MVC + EF Code First,但结合 WPF 和 EF Code First 的并不多。谢谢

标签: c# entity-framework .net-4.0 ef-code-first entity-framework-4.3


【解决方案1】:

通过不附加 LogEntry 实体来避免错误,而只是在数据库中查询 ChangedFiles 集合:

using (var db = new SourceLogContext())
{
    ChangedFiles = db.LogEntries.Where(x => x.LogEntryId == LogEntryId).Include(x => x.ChangedFiles).Single().ChangedFiles;
}

【讨论】:

    【解决方案2】:

    我实际上通过覆盖Equals()GetHashCode() 解决了这个问题:

    public override bool Equals(object obj)
    {
        var logEntry = obj as LogEntry;
        if (logEntry == null)
            return false;
        return LogEntryId.Equals(logEntry.LogEntryId);
    }
    
    public override int GetHashCode()
    {
        return LogEntryId.GetHashCode();
    }
    

    【讨论】:

      猜你喜欢
      • 2012-08-10
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-03-06
      • 2023-03-23
      • 1970-01-01
      • 2018-05-31
      • 1970-01-01
      相关资源
      最近更新 更多