I have an updatable view that is mapped in entity framework (edmx designer)
Everything works well and good until I add a property to my updatable view (and entity) that is marked with a StoreGeneratedPattern
of Computed
. Once I do that, upon saving my modified entity:
var user = objectContext.Users.FirstOrDefault(u => u.Id == 123);
// user is detached and some operations are performed...
// then it's re-attached to a new ObjectContext and has its ObjectStateEntry set to Modified
secondObjectContextInstance.SaveChanges() // throws exception:
The property 'Id' is part of the object's key information and cannot be modified.
at System.Data.Objects.EntityEntry.VerifyEntityValueIsEditable(StateManagerTypeMetadata typeMetadata, Int32 ordinal, String memberName)
at System.Data.Objects.EntityEntry.GetAndValidateChangeMemberInfo(String entityMemberName, Object complexObject, String complexObjectMemberName, StateManagerTypeMetadata& typeMetadata, String& changingMemberName, Object& changingObject)
at System.Data.Objects.EntityEntry.EntityMemberChanging(String entityMemberName, Object complexObject, String complexObjectMemberName)
at System.Data.Objects.EntityEntry.EntityMemberChanging(String entityMemberName)
at System.Data.Objects.ObjectStateEntry.System.Data.Objects.DataClasses.IEntityChangeTracker.EntityMemberChanging(String entityMemberName)
at System.Data.Objects.Internal.SnapshotChangeTrackingStrategy.SetCurrentValue(EntityEntry entry, StateManagerMemberMetadata member, Int32 ordinal, Object target, Object value)
at System.Data.Objects.Internal.EntityWrapper`1.SetCurrentValue(EntityEntry entry, StateManagerMemberMetadata member, Int32 ordinal, Object target, Object value)
at System.Data.Objects.EntityEntry.SetCurrentEntityValue(StateManagerTypeMetadata metadata, Int32 ordinal, Object userObject, Object newValue)
at System.Data.Objects.ObjectStateEntryDbUpdatableDataRecord.SetRecordValue(Int32 ordinal, Object value)
at System.Data.Mapping.Update.Internal.UpdateTranslator.SetServerGenValue(PropagatorResult context, Object value)
at System.Data.Mapping.Update.Internal.UpdateTranslator.BackPropagateServerGen(List`1 generatedValues)
at System.Data.Mapping.Update.Internal.UpdateTranslator.Update(IEntityStateManager stateManager, IEntityAdapter adapter)
at System.Data.EntityClient.EntityAdapter.Update(IEntityStateManager entityCache)
at System.Data.Objects.ObjectContext.SaveChanges(SaveOptions options)
at System.Data.Objects.ObjectContext.SaveChanges()
I have not changed the value of Id. In fact, I can reproduce this error if I don't change ANYTHING at all and simply re-attach to the second ObjectContext, set Modified, and call Save.
I can see the SQL generated for the update reflects that I have set this property as computed:
exec sp_executesql N'update [dbo].[UsersView]
set [UserName] = @0, [LastName] = @1, [FirstName] = @2, [MiddleName] = @3, [Suffix] = null, [Pid] = @4, [IsLoggedIn] = @5, [DisplayName] = @10
where ([Id] = @12)
select [ComputedProperty]
from [dbo].[UsersView]
where @@ROWCOUNT > 0 and [Id] = @12',N'@0 nvarchar(35),@1 nvarchar(35),@2 nvarchar(35),@3 nvarchar(35),@4 nvarchar(4),@5 bit,@6 bit,@7 bit,@8 nvarchar(max) ,@9 nvarchar(max) ,@10 nvarchar(max) ,@11 int,@12 int',@0=N'yaya',......
Again, everything works perfectly, without any problem until I set ComputedProperty to have a StoreGeneratedPattern of Computed. It seems like this must have something to do with the additional SELECT statement added to the update SQL in the above...because the exception happens AFTER the updates SQL is already executed.
What's wrong here?
Thanks.