实体框架4.0不适用于计算属性

时间:2012-01-02 01:34:03

标签: .net entity-framework entity-framework-4

我有一个可更新的视图,它映射在实体框架(edmx designer)

在我将可更新视图(和实体)添加到StoreGeneratedPattern Computed 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() 之前,一切都运行良好。一旦我这样做,保存我修改后的实体:

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',......

我没有更改Id的值。事实上,如果我根本不更改ANYTHING并且只是重新连接到第二个ObjectContext,设置Modified,并调用Save,我就可以重现这个错误。

我可以看到为更新生成的SQL反映出我已将此属性设置为computed:

{{1}}

同样,在我将ComputedProperty设置为StoreGeneratedPattern为Computed之前,一切都运行正常,没有任何问题。看起来这必须与上面添加到更新SQL的附加SELECT语句有关...因为异常发生在更新SQL已经执行之后。

这里有什么问题?

感谢。

2 个答案:

答案 0 :(得分:1)

将对象状态条目的状态设置为modified将导致将每个属性设置为已修改。相反,您应该只标记明确修改的属性,如本答案中所示。 Entity framework 4, update specific properties

答案 1 :(得分:0)

嗯,我想你可以称之为我自己的愚蠢,但这种行为有点不直观。

如果其他人实现INSTEAD OF触发器以通过EF启用可更新视图,则应注意此处描述的实现:error when inserting into table having instead of trigger from entity data framework应该仅用于INSTEAD OF INSERT触发器,而不是INSTEAD OF UPDATE触发器。将SELECT添加到而不是更新触发器的末尾将导致问题中描述的异常。