C# EF代码第一组<;tenty>;。已检测到对关系的角色的Attach()冲突更改

C# EF代码第一组<;tenty>;。已检测到对关系的角色的Attach()冲突更改,c#,entity-framework,.net-4.0,ef-code-first,entity-framework-4.3,C#,Entity Framework,.net 4.0,Ef Code First,Entity Framework 4.3,我有以下代码: 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

我有以下代码:

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)
发生System.InvalidOperationException

Message=检测到对关系“SourceLog.Model.LogEntry\u LogSubscription”的角色“LogEntry\u LogSubscription\u Target”的更改存在冲突。
Source=System.Data.Entity
堆栈跟踪:
位于System.Data.Objects.DataClasses.RelatedEnd.IncludeEntity(IEntityWrapper wrappedEntity、Boolean addRelationshipAsUnchanged、Boolean doAttach)
位于System.Data.Objects.DataClasses.EntityCollection`1.Include(Boolean addRelationshipAsUnchanged,Boolean doAttach)
位于System.Data.Objects.DataClasses.RelatedEnd.WalkObjectGraphToIncludeAllRelatedEntities(IEntityWrapper Wrappentity、Boolean addRelationshipAsUnchanged、Boolean doAttach)
位于System.Data.Objects.DataClasses.RelatedEnd.AddGraphToObjectStateManager(IEntityWrapper Wrappentity、Boolean relationshipAlreadyExists、Boolean addRelationshipAsUnchanged、Boolean doAttach)
位于System.Data.Objects.DataClasses.RelatedEnd.IncludeEntity(IEntityWrapper wrappedEntity、Boolean addRelationshipAsUnchanged、Boolean doAttach)
位于System.Data.Objects.DataClasses.EntityReference`1.Include(Boolean addRelationshipAsUnchanged,Boolean doAttach)
位于System.Data.Objects.DataClasses.RelationshipManager.AddRelatedEntities到ObjectStateManager(布尔doAttach)
位于System.Data.Objects.ObjectContext.AttachTo(字符串entitySetName,对象实体)
在System.Data.Entity.Internal.Linq.InternalSet`1.c\uu DisplayClass2

日志条目在此处分配了其日志订阅:

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


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

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

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

实际上,我在另一种情况下通过重写
Equals()
GetHashCode()
解决了这个问题:


是这样的吗?是的,是这样的(至少是相同的错误消息)。我已经看过那个帖子了,但不幸的是,它并没有帮我解决问题。我认为现在的情况是,LogEntry被分配给一个LogSubscription实例,然后添加到一个可观察的集合中,该集合以某种方式将LogSubscription引用更新到另一个实例(持有LogEntry集合的实例),EF在我尝试重新附加LogEntry时检测到这一点。看到您的代码,同样在你之前的问题之后,我再次觉得你应该重新思考你的架构。代码优先的目的是持久性。通过在实体对象中使用持久性代码(即上下文),您无法达到这一目的。这真臭。我可以想象它会引起各种副作用。例如:
LogEntry
对象由上下文具体化。对象将自身附加到另一个上下文。在这一点上,它总是脱离其原始上下文吗?使用实现INotifyPropertyChanged的视图模型。你的课太忙了。谢谢你的反馈@GertArnold。我完全可以在架构和模式方面进行指导。你知道有什么好文章/书我可以看吗?我首先看到了很多ASP.NETMVC+EF代码,但是没有多少先结合WPF和EF代码。。谢谢
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();
}