Chr*_*ris 12 c# oracle entity-framework
我们有一个Oracle表,其中包含三列的复合键.这些列通过实体框架数据模型正确映射到C#对象.当我们从数据库查询记录然后更新非键列时,我们总是会收到一条错误消息,说我们正在尝试更新主键(下面是测试的摘录):
var connection = new DbContextProvider(() => new DatabaseConnection());
var repo = new Repository(connection);
var deltas = repo.Queryable<Deltas>().Where(d =>d.Volume.SubmissionId == 88921).ToList();
var deltaToUpdate = deltas.First();
deltaToUpdate.RecordedVolume = 0;
repo.Flush(); -- Does a context.SaveChanges() in background
Run Code Online (Sandbox Code Playgroud)
我们总是收到以下信息:
System.InvalidOperationException:属性"COPY_ID"是对象的密钥信息的一部分,无法修改.
COPY_ID是密钥的一部分,但是StoredGeneratedPettern = Identity,并且在事务中不会更改.
任何帮助赞赏.
这是完整的堆栈:
System.InvalidOperationException:属性"COPY_ID"是对象的密钥信息的一部分,无法修改.at Data.Objects.EntityEntry.VerifyEntityValueIsEditable(StateManagerTypeMetadata typeMetadata,Int32 ordinal,String memberName)
at System.Data.Objects.EntityEntry.GetAndValidateChangeMemberInfo(String entityMemberName,Object complexObject,String complexObjectMemberName,ref StateManagerTypeMetadata typeMetadata,ref String changingMemberName,ref 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)
在System.Data.Objects.Internal.SnapshotChangeTrackingStrategy.SetCurrentValue(EntityEntry条目,StateManagerMemberMetadata成员,Int32序数,对象目标,对象值)
在System.Data.Objects.Internal.EntityWrapper`1.SetCurrentValue(EntityEntry条目,StateManagerMemberMetadata成员,Int32序数,对象目标,对象值)
在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.Objects.DbUpdatableDataRecord.SetValue(Int32 ordinal,Object value)
在System.Data.Mapping.Update.Internal.UpdateTranslator.SetServerGenValue(P ropagatorResult context,Object value)
在System.Data.Mapping.Update.Internal.UpdateTranslator.BackPropagateServerGen(List`1 generatedValues)
在System.Data.Mapping.Update.Internal.UpdateTranslator.Update(IEntityStateManager stateManager,IEntityAdapter adapter)
在System.Data.EntityClient.EntityAdapter.Update(IEntityStateManager entityCache)
处于System.Data.Entity.InternalContext.SaveChanges()的System.Data.Entity.InternalContext.SaveChanges()处的System.Data.Objects.ObjectContext.SaveChanges(SaveOptions选项)处的System.Data.Entity.LazyInternalContext.SaveChanges()处于System.Data.Entity.DbContext .保存更改()
更新 我们已经跟踪了数据库交互,看来以下SQL正在数据库上成功运行,当它返回EF时抛出错误(并且未提交更改):
declare
"COPY_ID" number(10,0);
"CODS_ID" number(10,0);
"PERIOD_ID" number(7,0);
begin
update "SCHEMA"."TABLE"
set "COLUMN" = :p0
where ((("COPY_ID" = :p1)
and ("CODS_ID" = :p2))
and ("PERIOD_ID" = :p3))
returning "COPY_ID", "CODS_ID", "PERIOD_ID" into "COPY_ID", "CODS_ID", "PERIOD_ID";
open :p4
for select "COPY_ID" as "COPY_ID", "CODS_ID" as "CODS_ID", "PERIOD_ID" as "PERIOD_ID"
from dual;
end;
{ :p0=[Decimal,0,Input]0, :p1=[Int32,0,Input]222222, :p2=[Int32,0,Input]22222, :p3=[Int32,0,Input]222222, :p4=[Object,0,Output]NULL }
Run Code Online (Sandbox Code Playgroud)
请包括:
查看堆栈跟踪,我看到的关键是BackPropagateServerGen.
实体框架正在针对数据库运行您的更新,但您的复合键值之一(可能是 COPY_ID)实际上已被 UPDATE 调用更改。服务器生成的值从 SQL 调用返回,然后实体框架抱怨该键值正在从其下方更改。
因此,我猜测您的 COPY_ID 复合键值被定义为服务器生成的标识符,但其中之一或两者都发生了:
如果您有任何触发器,请暂时禁用它们,看看问题是否会停止。
如果要映射到视图或存储过程,请尝试直接映射到表(如果可能)。
使用您拥有的任何分析工具来捕获代码正在执行的 SQL。
我认为 UPDATE 调用实际上到达了数据库,但返回结果正在更改键值,导致实体框架失败,并可能回滚 UPDATE 事务(取决于您使用的 EF 版本)。
| 归档时间: |
|
| 查看次数: |
1325 次 |
| 最近记录: |