[英]Two many-to-one table relationships and insertion with Entity Framework
[英]Empty rows insertion in Many-to-One and Many-to-Many relationships in GraphDiff
我使用GraphDiff,以及最新版本的Entity Framework,遵循代碼優先的方法。
我試圖通過這種方式更新Food
實體:
public void Update(Food food)
{
using (var db = new DatabaseMappingContext())
{
food = db.UpdateGraph(food, map => map.OwnedEntity(f => f.FoodRecipe, withRecipe => withRecipe.
OwnedCollection(r => r.RecipeSteps, withRecipeStep => withRecipeStep.
OwnedCollection(rs => rs.StartObjectSlots, withStartObjectSlots => withStartObjectSlots.
AssociatedEntity(sos => sos.BelongingRecipeStepAsStart)
).
OwnedCollection(rs => rs.EndObjectSlots, withEndObjectSlots => withEndObjectSlots.
AssociatedEntity(eos => eos.BelongingRecipeStepAsEnd)
).
AssociatedEntity(rs => rs.ActionOfUser)
).
AssociatedCollection(r => r.InteractiveObjects)
).
AssociatedCollection(f => f.FoodVarieties));
//....
db.SaveChanges();
}
}
StartObjectSlots
和EndObjectSlots
是包含一些其他無關數據的2個列表。 InteractiveObjects
包含InteractiveObject
類型的對象,該類型是可以放在那里的許多對象類型的基本類型。 其中一個派生類型(假設IntObjDerived
具有一對多屬性)。 現在,我試圖以這種方式更新以下實體:
ServerAdapter sa = new ServerAdapter();
//Loading a food from DB.
Food food = sa.LoadAllFoods().First();
RecipeStep rs = new RecipeStep();
rs.Name = "This is a test recipe step";
//Adding a User Action from the database.
rs.ActionOfUser = sa.LoadAllUserActions().First();
//....
//Add the step in the recipe
food.FoodRecipe.RecipeSteps.Add(rs);
//Update the food.
sa.Update(food);
現在,當執行代碼時,會將新的空ActionOfUser實體插入到數據庫中。 另外, 為上述實體的每對一對多導航屬性插入一個新的空實體 在數據庫中插入了三個新配方,一個是空數據,一個是填充的,一個應該保存。 這兩種情況都是不受歡迎的,我試圖找到解決方案。 我嘗試了一些改變,但我堅持這一點。 有什么建議么? (我知道這似乎是2個問題,但我想把它作為一個,因為它可能是相關的 - 數據庫中的相同問題)。
編輯:我下載並編譯了GraphDiff
以檢查發生了什么,我注意到除了實體ID值之外,還創建了一些空的對象。 我猜這些副作用是因為我實際上在對象圖中添加了一個新節點(一個新的RecipeStep),我不確定graphdiff是否完全支持這個。
更新( tl; dr
版本):我嘗試使用Entity Framework的GraphDiff對圖形深度大於2的對象應用UpdateGraph
調用。通過我的嘗試,似乎GraphDiff在深度大於2的圖形中應用雙重插入並且需要花費大量時間,尤其是在添加了從數據庫加載的子節點的新節點時。 我應該采用不同的方法,例如將UpdateGraph
調用分成多個調用嗎?
先感謝您!
我最終應用的解決方法是通過將其拆分為圖形深度小於或等於2的多個UpdateGraph
調用來執行更新操作,並手動應用任何子節點添加到圖形中:
//Update food in total graph depth <= 2.
db.UpdateGraph(food, map => map.AssociatedCollection(f => f.FoodVarieties));
//.... (Other UpdateGraph calls with graph depth <=2)
//Update recipe steps of recipe in total graph depth <= 2.
foreach (RecipeStep recipeStep in food.FoodRecipe.RecipeSteps)
{
recipeStep.ActionOfUser = db.UserActions.FirstOrDefault(ua => ua.EntityID == recipeStep.ActionOfUser.EntityID);
//If you have to do an inner node adding operation in the graph, do it manually.
if (recipeStep.EntityID == 0)
{
recipeStep.BelongingRecipe = db.Recipes.FirstOrDefault(r => r.EntityID == food.FoodRecipe.EntityID);
db.RecipeSteps.Add(recipeStep);
}
else
{
//Map slots & recipeSteps applied manually here.
recipeStep.StartObjectSlots.ForEach(sos => sos.BelongingRecipeStepAsStart = recipeStep);
recipeStep.EndObjectSlots.ForEach(eos => eos.BelongingRecipeStepAsEnd = recipeStep);
db.UpdateGraph(recipeStep, map => map.OwnedCollection(rs => rs.InteractiveObjectInstancesLists, withIOILists => withIOILists.
OwnedCollection(ioil => ioil.InteractiveObjectsInstances)
).
OwnedCollection(rs => rs.StartObjectSlots, withStartObjectSlots => withStartObjectSlots.
AssociatedEntity(sos => sos.BelongingRecipeStepAsStart)
).
OwnedCollection(rs => rs.EndObjectSlots, withEndObjectSlots => withEndObjectSlots.
AssociatedEntity(eos => eos.BelongingRecipeStepAsEnd)
).
AssociatedEntity(rs => rs.ActionOfUser)
);
}
}
此外,我注意到對象的圖形更新比以前更快完成。 在去錯的東西 ,這些可能是適應症GraphDiff
復雜的圖形(> 2深度)更新過程(或至少我在做一些可怕的錯誤)。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.