簡體   English   中英

EF 6 保存多個級別的子實體和多個父實體

[英]EF 6 Saving multiple levels of child entities and multiple parents

鑒於此模型:

帶孩子的模特

我希望能夠在一個 SaveChange 調用中保存關系。 這意味着,我有一個新的或更新的 ContainerParent,以及多個第一級子級,每個子級都可以有 1 或 2 個更深的級別。

問題是,孩子們都有一個自己的鑰匙,用於找到它的父母,還有一個容器的鑰匙,讓容器獨立於其層次級別獲取所有孩子。

用這個偽代碼(在所有實體都被創建的情況下,沒有更新)

var newContainerParent = context.ContainerParents.Add(new ContainerParent());
var rootChild = context.Children.Add(new Child());

var secondLevelChild = new Child();
var thirdLevelChild = new Child();
secondLevelChild.Children.Add(thirdLevelChild);

rootChild.Children.Add(secondLevelChild);
newContainerParent.Children.Add(rootChild);

context.SaveChanges();

此代碼的問題在於,只有 rootchild 具有容器集的 FK。 我還嘗試將孩子添加到他們的孩子父母和容器中:

rootChild.Children.Add(secondLevelChild);
newContainerParent.Children.Add(rootChild);
newContainerParent.Children.Add(secondLevelChild);
newContainerParent.Children.Add(thirdLevelChild);

我在用新孩子更新現有容器時遇到同樣的問題。 我使用父項已經存在的鍵設置了所有子項,但是當調用 SaveChanges 時,該鍵沒有保存,它恢復為 null。

我通過分兩步完成所有這些來修復它,保存一次,然后獲取所有新創建的子項並使用父鍵更新它們,再次調用 SaveChanges。

我有一種感覺,我錯過了一些東西,我不需要保存兩次。

SaveChange 調用的數量或頻率對任何事情都沒有影響,對性能等沒有影響。 那么為什么要最小化它呢?

實際上,用一個 SaveChanges 存儲這樣一個自引用表是不可能的,因為在保存時會生成一個新實體的 ID。 因此,您首先需要保存它,然后獲得可以存儲在另一個實體中的 ID。 這可能需要對您剛剛存儲的實體進行進一步的更新命令。

你有兩次機會來解決這個問題。

1) 手動生成的 ID,自己處理,並且在存儲之前知道 ID。

2)如果您的依賴項中沒有循環性,那么完美的樹結構,您可以自上而下地逐級保存項目。 我假設你有孩子有參考它的父母,所以根沒有參考任何其他項目,你首先保存它,而不是第一級孩子,依此類推。

這需要多個 SaveChanges,但這不是缺點。 無論如何,每個實體都是一個 Insert-SQL-Command,無論您是在 1 SaveChanges 中還是在 100 SaveChanges 中執行此操作。

這兩種解決方案都避免了對實體的“更新”命令,它們只執行插入。

實體框架實際上可以自己找出這種依賴關系並創建新實體插入的順序,但這在今天沒有實現,或者並不完美,尤其是在自引用表上。 保存項目的順序是隨機的。 因此,您必須使用中間 SaveChanges 強制執行訂單。

暫無
暫無

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

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