0

Мы столкнулись с этой ошибки на конкретном запросе в нашем приложении около 1 в 3 раза:Свойство «Id» является частью ключевой информации объекта и не может быть изменен на SELECT

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

ошибка сообщение & Google предполагают, что эта ошибка возникает при попытке изменить значение Id. Однако это всего лишь оператор select, мы ничего не изменяем в этом запросе. Обратите внимание, что другие запросы выполнялись в DbContext до этого, поэтому другие объекты уже могут быть в контексте.

Зачем это происходит в инструкции выбора?

Почему это происходит только раз в 1 раз в 3 раза?

Какие факторы компаундирования могут способствовать этому сообщению об ошибке?

+0

Ошибка может возникнуть там, где сообщается об ошибке. Забавные вещи случаются, когда у вас нет обработчиков исключений (try/catch) в каждом методе. Когда возникает исключение, скомпилированный код перемещает стек выполнения до тех пор, пока не будет найден первый обработчик. Linq имеет встроенный обработчик исключений. Таким образом, ошибка возникает до того, как этот код будет выполнен. Найдите код, который действительно меняет идентификатор. – jdweng

+0

Спасибо, трассировка стека, которую я вижу в исключении, совпадает с точкой останова, поэтому я считаю, что она встречается в указанном месте. Похоже, что это происходит внутри Entity Framework, когда выполняется запрос ToList(). –

ответ

0

Я нашел причину.

Оказывается, тот же DbContext использовался одновременно в нескольких потоках. EF6 не является потокобезопасным для этого использования, поэтому происходят случайные внутренние ошибки.