【发布时间】:2015-10-01 09:18:52
【问题描述】:
我们在应用程序中的特定查询中遇到此错误的概率约为 3 次:
The property 'Id' is part of the object's key information and cannot be modified.
at System.Data.Entity.Core.Objects.EntityEntry.VerifyEntityValueIsEditable(StateManagerTypeMetadata typeMetadata, Int32 ordinal, String memberName)
at System.Data.Entity.Core.Objects.EntityEntry.GetAndValidateChangeMemberInfo(String entityMemberName, Object complexObject, String complexObjectMemberName, StateManagerTypeMetadata& typeMetadata, String& changingMemberName, Object& changingObject)
at System.Data.Entity.Core.Objects.EntityEntry.EntityMemberChanging(String entityMemberName, Object complexObject, String complexObjectMemberName)
at System.Data.Entity.Core.Objects.EntityEntry.EntityMemberChanging(String entityMemberName)
at System.Data.Entity.Core.Objects.ObjectStateEntry.System.Data.Entity.Core.Objects.DataClasses.IEntityChangeTracker.EntityMemberChanging(String entityMemberName)
at System.Data.Entity.Core.Objects.Internal.SnapshotChangeTrackingStrategy.SetCurrentValue(EntityEntry entry, StateManagerMemberMetadata member, Int32 ordinal, Object target, Object value)
at System.Data.Entity.Core.Objects.Internal.EntityWrapper`1.SetCurrentValue(EntityEntry entry, StateManagerMemberMetadata member, Int32 ordinal, Object target, Object value)
at System.Data.Entity.Core.Objects.DataClasses.EntityReference.UpdateForeignKeyValues(IEntityWrapper dependentEntity, IEntityWrapper principalEntity, Dictionary`2 changedFKs, Boolean forceChange)
at System.Data.Entity.Core.Objects.DataClasses.EntityReference.UpdateDependentEndForeignKey(RelatedEnd targetRelatedEnd, Boolean forceForeignKeyChanges)
at System.Data.Entity.Core.Objects.DataClasses.RelatedEnd.Add(IEntityWrapper wrappedTarget, Boolean applyConstraints, Boolean addRelationshipAsUnchanged, Boolean relationshipAlreadyExists, Boolean allowModifyingOtherEndOfRelationship, Boolean forceForeignKeyChanges)
at System.Data.Entity.Core.Objects.DataClasses.RelatedEnd.Add(IEntityWrapper wrappedEntity, Boolean applyConstraints)
at System.Data.Entity.Core.Objects.DataClasses.EntityReference`1.set_ReferenceValue(IEntityWrapper value)
at System.Data.Entity.Core.Objects.DataClasses.EntityReference.SetEntityKey(EntityKey value, Boolean forceFixup)
at System.Data.Entity.Core.Objects.EntityEntry.FixupEntityReferenceToPrincipal(EntityReference relatedEnd, EntityKey foreignKey, Boolean setIsLoaded, Boolean replaceExistingRef)
at System.Data.Entity.Core.Objects.EntityEntry.FixupReferencesByForeignKeys(Boolean replaceAddedRefs, EntitySetBase restrictTo)
at System.Data.Entity.Core.Objects.ObjectStateManager.FixupReferencesByForeignKeys(EntityEntry newEntry, Boolean replaceAddedRefs)
at System.Data.Entity.Core.Objects.ObjectStateManager.AddEntry(IEntityWrapper wrappedObject, EntityKey passedKey, EntitySet entitySet, String argumentName, Boolean isAdded)
at System.Data.Entity.Core.Common.Internal.Materialization.Shaper.HandleEntity[TEntity](IEntityWrapper wrappedEntity, EntityKey entityKey, EntitySet entitySet)
at lambda_method(Closure , Shaper )
at System.Data.Entity.Core.Common.Internal.Materialization.Coordinator`1.ReadNextElement(Shaper shaper)
at System.Data.Entity.Core.Common.Internal.Materialization.Shaper`1.RowNestedResultEnumerator.MaterializeRow()
at System.Data.Entity.Core.Common.Internal.Materialization.Shaper`1.RowNestedResultEnumerator.MoveNext()
at System.Data.Entity.Core.Common.Internal.Materialization.Shaper`1.ObjectQueryNestedEnumerator.TryReadToNextElement()
at System.Data.Entity.Core.Common.Internal.Materialization.Shaper`1.ObjectQueryNestedEnumerator.ReadElement()
at System.Data.Entity.Core.Common.Internal.Materialization.Shaper`1.ObjectQueryNestedEnumerator.MoveNext()
at System.Data.Entity.Internal.LazyEnumerator`1.MoveNext()
at System.Collections.Generic.List`1..ctor(IEnumerable`1 collection)
at System.Linq.Enumerable.ToList[TSource](IEnumerable`1 source)
....project specific stack elements
有问题的查询是简单的选择查询:
var set = ObjectContext.CreateObjectSet<TModel>();
set = set.WithMergeOption(MergeOption.OverwriteChanges)
var results = set.Where(p => (!p.IsArchived && !p.IsDeleted))
.Include(w => w.CurrentPlaceStructure)
.Include(o => o.Room.Wing.Location)
.Include(r => r.Residencies)
.Include(r => r.PlaceStructures)
.Include(r => r.Room.RoomStructures)
.ToList();
错误信息&谷歌提示尝试修改Id值时会出现此错误。然而,这只是一个选择语句,我们不会修改此查询中的任何内容。请注意,在此之前其他查询已在 DbContext 上运行,因此其他对象可能已经在上下文中。
为什么会在 select 语句中出现这种情况?
为什么它只会出现大约每 3 次中的 1 次?
哪些复合因素可能导致此错误消息?
【问题讨论】:
-
报告错误的地方可能不会发生错误。当您在每个方法中都没有异常处理程序(try/catch)时,就会发生有趣的事情。当发生异常时,编译后的代码会向上移动执行堆栈,直到找到第一个异常处理程序。 Linq 内置了异常处理程序。因此,在执行此代码之前就发生了错误。找到真正改变 id 的代码。
-
谢谢,我在异常中看到的堆栈跟踪与引发的断点匹配,所以我相信它发生在指定的位置。在执行 ToList() 查询时,它似乎发生在 Entity Framework 内部。
标签: c# entity-framework linq-to-entities invalidoperationexception entity-framework-6.1