4

コード ファーストのアプローチに従って、最新バージョンの Entity Framework と共に GraphDiff を使用しています。

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();
    }
}

StartObjectSlotsEndObjectSlotsは、他の無関係なデータを含む 2 つのリストです。には、そこに置くことができる多くのオブジェクト タイプの基本タイプであるタイプのオブジェクトInteractiveObjectsが含まれています。これらの派生型の 1 つ ( 1 対多のプロパティがある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 エンティティがデータベースに挿入されます。さらに、上記のエンティティの 1 対多のナビゲーション プロパティごとに、新しい空のエンティティが挿入されます。3 つの新しいレシピがデータベースに挿入されます。1 つは空のデータ、もう 1 つは半分が入力されたもの、もう 1 つは保存されるはずです。どちらの状況も望ましくないため、解決策を見つけようとしています。いくつかの変更を試しましたが、これに固執しました。助言がありますか?(これは2つの質問のようですが、データベースに関連する可能性があるため、1つにまとめることを考えました)。

編集:GraphDiff何が起こっているのかを調べるためにダウンロードしてコンパイルしましたが、エンティティ ID 値以外は空のオブジェクトがいくつか作成されていることに気付きました。これらの副作用は、実際にはオブジェクト グラフ (新しい RecipeStep) に新しいノードを追加し、graphdiff がこれを完全にサポートしているかどうかわからないために発生すると思います。

更新 (tl; drバージョン):UpdateGraphグラフの深さが 2 より大きいオブジェクトの Entity Framework の GraphDiff を使用して呼び出しを適用しようとしました。特に、データベースからサブノードがロードされた新しいノードが追加された場合。たとえば、UpdateGraph呼び出しを複数の呼び出しに分割するなど、別のアプローチに従う必要がありますか?

前もって感謝します!

4

1 に答える 1

1

UpdateGraph私が最終的に回避策として適用したのは、グラフの深さが 2 以下の複数の呼び出しに分割して更新操作を実行し、グラフにサブノードの追加を手動で適用することでした。

//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)
        );

    }
}

また、オブジェクトのグラフの更新が以前よりもはるかに高速に完了していることに気付きました。これらは、複雑なグラフ (> 2 の深さ) の更新プロセスで何かがうまくいかGraphDiffないことを示している可能性があります (または、少なくとも私は何かひどく間違ったことをしていました)。

于 2014-12-25T12:27:52.973 に答える