简体   繁体   English

在GraphDiff中的多对一和多对多关系中的空行插入

[英]Empty rows insertion in Many-to-One and Many-to-Many relationships in GraphDiff

I am using GraphDiff, along with the latest version of the Entity Framework, following the code-first approach. 我使用GraphDiff,以及最新版本的Entity Framework,遵循代码优先的方法。

I am trying to update a Food entity this way: 我试图通过这种方式更新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 and EndObjectSlots are 2 lists containing some other, irrelevant data. StartObjectSlotsEndObjectSlots是包含一些其他无关数据的2个列表。 The InteractiveObjects contains objects of a InteractiveObject type, which is the base type for a number of object types that can be put there. InteractiveObjects包含InteractiveObject类型的对象,该类型是可以放在那里的许多对象类型的基本类型。 One of those derived types (let's say IntObjDerived has a One-to-Many property). 其中一个派生类型(假设IntObjDerived具有一对多属性)。 Now, I am trying to update the following entity this way: 现在,我试图以这种方式更新以下实体:

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

Now, when the code is executed, a new empty ActionOfUser entity is inserted into the database. 现在,当执行代码时,会将新的空ActionOfUser实体插入到数据库中。 Additionally, 另外, a new empty entity is inserted for each of the one-to-many navigation properties of the entities mentioned above 为上述实体的每对一对多导航属性插入一个新的空实体 three new recipes are inserted in the database, one of empty data, one half filled and this one supposed to be saved. 在数据库中插入了三个新配方,一个是空数据,一个是填充的,一个应该保存。 Both situations are unwanted, and I am trying to find the solution. 这两种情况都是不受欢迎的,我试图找到解决方案。 I experimented with some changes, but I have stuck with this. 我尝试了一些改变,但我坚持这一点。 Any suggestions? 有什么建议么? (I know that this seems to be 2 questions, but I thought to put it as one as it might be relevant-same problem in database). (我知道这似乎是2个问题,但我想把它作为一个,因为它可能是相关的 - 数据库中的相同问题)。

EDIT: I downloaded and compiled GraphDiff in order to inspect what is going on, and I noticed the creation of some objects that are empty except from their Entity ID value. 编辑:我下载并编译了GraphDiff以检查发生了什么,我注意到除了实体ID值之外,还创建了一些空的对象。 I guess that those side effects are caused because practically I add a new node to the object graph (a new RecipeStep) and I am not sure if graphdiff fully supports this. 我猜这些副作用是因为我实际上在对象图中添加了一个新节点(一个新的RecipeStep),我不确定graphdiff是否完全支持这个。

UPDATE ( tl; dr version): I tried to apply a UpdateGraph call using Entity Framework's GraphDiff of an object with graph depth greater than 2. By what I have tried, it seems that GraphDiff is applying double insertions in graphs of depth greater than 2 and it takes a lots of time, especially if a new node is added with subnodes loaded from the database. 更新( tl; dr版本):我尝试使用Entity Framework的GraphDiff对图形深度大于2的对象应用UpdateGraph调用。通过我的尝试,似乎GraphDiff在深度大于2的图形中应用双重插入并且需要花费大量时间,尤其是在添加了从数据库加载的子节点的新节点时。 Should I follow a different approach, for example split the UpdateGraph call into multiple calls? 我应该采用不同的方法,例如将UpdateGraph调用分成多个调用吗?

Thank you in advance! 先感谢您!

What I finally applied as a workaround, was to perform the update operation by splitting it into multiple UpdateGraph calls with graph depth less than or equal to 2 and apply manually any sub-node addition to the graph: 我最终应用的解决方法是通过将其拆分为图形深度小于或等于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)
        );

    }
}

Also, I noticed that the object's graph update was completed much faster than before. 此外,我注意到对象的图形更新比以前更快完成。 These might be indications of something going wrong in GraphDiff complex graph (>2 depth) updating process (or at least I was doing something terribly wrong). 去错东西 ,这些可能是适应症GraphDiff复杂的图形(> 2深度)更新过程(或至少我在做一些可怕的错误)。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM