我正在使用 C#、物體框架、ASP.NET Core MVC 和 SQL Server
總而言之,我使用迭代來一個一個地插入多個物體,因此我可以從.SaveChangesAsync().
問題是,似乎新插入的行在下一次插入時未被識別,這使得框架或資料庫嘗試創建插入到同一 ID 中。
foreach (var concessao in Concessoes)
{
_context.Add(concessao);
var resultado = await _context.SaveChangesAsync();
}
我清除了一些代碼以使其更簡單。我知道我可以一次插入多個物體。但我想得到所有這些的結果,而不是整個操作的結果。
發生的情況示例(使用除錯器和資料庫檢查):
- 現有 ID 從 1 到 8。
- 嘗試插入 2 個新物體
- 第一個物體映射到 ID 9。
- 第二個物體也映射到 ID 9,所以我得到:
InvalidOperationException:屬性“ConcessaoCreditoAluno.IdConcessaoCreditoAluno”是密鑰的一部分,因此無法修改或標記為已修改。要使用標識外鍵更改現有物體的主體,首先洗掉依賴項并呼叫“SaveChanges”,然后將依賴項與新主體關聯。`
對我來說,似乎第一個新插入的物體在插入第二個物體之前沒有被識別,就好像它不存在一樣。就像我應該關閉資料庫并重新打開它以在插入新資料庫之前更新它一樣。但如果是這種情況,我不知道該怎么做。
uj5u.com熱心網友回復:
該錯誤指的是“ConcessaoCreditoAluno”,我猜它是您嘗試保存的 Concessoa 物體中參考的物體。
在處理對同一物體的多個參考時,通常會發生這些錯誤。檢查集合中的所有實體及其相關實體是否是新的、不同的類實體,并且您的物體映射對于您要強制執行的關系型別是否有效:
基于例外,我猜測兩個 Concessoa 記錄(A 和 B)都參考了 ConcessaoCredtoAluno 的同一個實體。但是,EF 將這種關系解釋為 ConcessaoCreditoAluno 關系是排他性的,第二次保存嘗試更改 Key 值。
想到的可能原因可能是外鍵關系不匹配,其中 CocessaoCreditoAlunoId 被映射到 Concessoe 表中的 ConcessoaId。如果 EF 配置為期望這是一對一關系,而沒有在一側或另一側映射的顯式 FK,則可能會發生這種情況。(即 Concessoe 具有 FK 的 ConcessoCreditoAlunoId 或 CocessoaCreditoAluno 具有 FK 的 ConcessoaId)如果兩個 Concessao
例如,這說明了這個問題:
var concessaoCreditoAluno = new ConcessaoCreditoAluno {Name = "Test"};
var concessoaA = new Concessoa {Name = "A", ConcessaoCreditoAluno = concessaoCreditoAluno};
var concessoaB = new Concessoa {Name = "B", ConcessaoCreditoAluno = concessaoCreditoAluno};
context.Concessoes.Add(concessoaA);
context.SaveChanges();
context.Concessoes.Add(concessoaB);
context.SaveChanges();
這里的問題是 A 和 B 都參考了 CreditoAluno 的同一個實體。當“A”被保存時,資料庫將它的 ConcessoaId 分配給“8”,并將 CreditorAluno 的 ID 分配給匹配。一切都很好。但是,當它去保存“B”時,它將 B 的 ConcessoaId 分配給“9”并嘗試更新關聯的 Aluno 的“Key”以匹配,導致它嘗試更改被跟蹤物體的鍵的錯誤。它正在參考同一個實體。
解決方案是,如果這確實是一個一對一的關系,其中兩個 Concessoa 都參考了一個不同的 CreditoAluno,那么您需要確保這些是單獨的參考:
var concessaoCreditoAlunoA = new ConcessaoCreditoAluno {Name = "Test"};
var concessaoCreditoAlunoB = new ConcessaoCreditoAluno {Name = "Test"};
var concessoaA = new Concessoa {Name = "A", ConcessaoCreditoAluno = concessaoCreditoAlunoA};
var concessoaB = new Concessoa {Name = "B", ConcessaoCreditoAluno = concessaoCreditoAlunoB};
context.Concessoes.Add(concessoaA);
context.SaveChanges();
context.Concessoes.Add(concessoaB);
context.SaveChanges();
如果 ConcessaoCreditoAluno 可以在 Concessoa 實體之間共享,那么映射需要從一對一更改為多對一,其中 Concessoa 需要使用映射映射 ConcessaoCreditoAlunoId HasOne().WithMany()。
uj5u.com熱心網友回復:
添加到整個背景關系中總是個壞主意。嘗試添加到dbset,最好添加range而不是使用loop
_context.Set<Concessoe>().AddRange(Concessoes);
var resultado = await _context.SaveChangesAsync();
轉載請註明出處,本文鏈接:https://www.uj5u.com/caozuo/330733.html
