簡體   English   中英

嘗試使用實體框架將記錄插入SQL Server時違反主鍵錯誤

[英]Violation of Primary Key error when trying to insert record into SQL Server using Entity Framework

違反PRIMARY KEY約束“ PrimaryKeyId”。 無法在對象“ dbo.Table”中插入重復鍵。 重復的鍵值為(xxx)。\\ r \\ n該語句已終止。

這種情況已經發生了好幾周了,每次我都認為已修復時,它就會在幾天后彈出。 我在用:

dbContext.Table.Add(myObject);
dbContext.SaveChanges();

這是在using語句中,試圖添加一個當前ID為0的對象PrimaryKeyId是表中的標識,並設置為自動遞增1。但是,Entity Framework似乎采用了隨機ID,並且嘗試將其分配給我的對象,然后將所述對象添加到數據庫。

這僅在該一張表上發生,並且在許多其他表上使用相同的過程也沒有任何問題。 所作用的表的設置與使用此過程的其他表相同,沒有錯誤。 關於什么可能導致此的任何想法? 為了明確起見,實體框架似乎正在嘗試將已經存在的主鍵分配給新對象。

解決我特定問題的方法:Tar和羽毛DBA

說明:在運行冗長/復雜的導入腳本時,我們的DBA對其進行了設置,以重新設置表的x位置,該位置遠低於標識列中的當前值。 因此,在過去的幾周內,從技術上講沒有問題,這只是人為錯誤。 這個問題可能/應該/應該被拖到一個木棚后面,擺脫困境。 順帶一提/輕描淡寫是他的建議(未經同事的同意,我不贊成虐待同事)。

如果未刪除此問題,建議的解決方法是使用以下命令檢查表上的當前標識值

 select ident_current('tableName') 

並將其與表格中的最高值進行比較。 尤其是在通過腳本進行手動導入/修改的情況下,可以手動重置種子。

這應該被證明是有幫助的(特別是我用粗體顯示的那一部分):摘自使用實體密鑰

實體鍵和添加的對象

創建新實體時,實體框架會定義臨時鍵並將IsTemporary屬性設置為true。 當您調用SaveChanges方法時,實體框架將分配一個永久密鑰並將IsTemporary屬性設置為false。

如果相應的列值是數據庫中生成的標識,則將存儲模型中實體的property元素的StoreGeneratedPattern屬性設置為Identity 當實體數據模型工具從現有數據源生成數據模型時, StoreGeneratedPattern屬性添加到表示數據源中的標識或計算列的每個屬性元素(CSDL)元素。 在調用SaveChanges之后,實體框架用數據源生成的標識值替換臨時鍵中的屬性值。

以下詳細說明了內部過程,該過程將臨時密鑰替換為包含服務器生成的值的永久密鑰:

  • 實體對象被構造。
  • 此時,鍵屬性都具有默認值,即null或0。
  • 通過在ObjectContextObjectSet上調用AddObject方法,或通過在關系的“許多”端將對象添加到對象集合中,可以將新對象添加到ObjectContext中。
  • 此時,實體框架生成一個臨時密鑰,該密鑰用於將對象存儲在ObjectStateManager
  • 在ObjectContext上調用SaveChanges
  • INSERT語句由實體框架生成,並在數據源上執行。
  • 如果INSERT操作成功,則服務器生成的值將寫回到ObjectStateEntry
  • ObjectStateEntry使用服務器生成的值更新對象。
  • ObjectStateEntryAcceptChanges ,將使用新的服務器生成的值來計算永久性EntityKey
  • SaveChanges執行結束時,或者使用AcceptAllChangesAfterSave標志調用SaveChanges方法時,將自動AcceptChanges
  • ObjectStateManager用新的永久密鑰替換臨時密鑰的所有實例。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM