EF Code First IDbSet <tentity> .Attach()已检测到关系_的角色_的冲突更改</tentity>

时间:2012-11-01 09:32:37

标签: 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_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的collection属性中,但不加载整个LogEntry集合。这是正确的方法吗?

2 个答案:

答案 0 :(得分:0)

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

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

答案 1 :(得分:0)

我实际上通过覆盖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();
}