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();
}