[英]Entity Framework Can't Update Data In Table With Composite Key (Oracle)
我們有一個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
我們總是收到以下信息:
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 }
請包括:
查看堆棧跟蹤,我看到的關鍵是BackPropagateServerGen
。
實體框架正在針對數據庫運行更新,但是您的一個復合鍵值(可能是COPY_ID)實際上正被UPDATE調用更改。 此服務器生成的值將從SQL調用返回,然后實體框架抱怨密鑰值正在從其下面更改。
所以,我猜你的COPY_ID復合鍵值被定義為服務器生成的標識符,但是其中一個或兩個都發生了:
如果您有任何觸發器,請暫時禁用它們以查看問題是否會停止。
如果要映射到視圖或存儲過程,請嘗試直接映射到表。
使用您擁有的任何分析工具來捕獲代碼正在執行的SQL。
我認為UPDATE調用實際上是到達數據庫,但返回結果是更改鍵值,導致實體框架失敗,並可能回滾UPDATE事務(取決於您使用的EF版本)。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.