简体   繁体   English

EF 6 保存多个级别的子实体和多个父实体

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

Given this model:鉴于此模型:

带孩子的模特

I would like to be able to save in one SaveChange call the relations.我希望能够在一个 SaveChange 调用中保存关系。 Which means, I either have a new or updated ContainerParent, and multiple first level children and each of those can have 1 or 2 levels deeper.这意味着,我有一个新的或更新的 ContainerParent,以及多个第一级子级,每个子级都可以有 1 或 2 个更深的级别。

The thing is, the children both have a key to themselves, for finding its parent, and a key to the container, for the container to get all its Children independently of their hierarchical level.问题是,孩子们都有一个自己的钥匙,用于找到它的父母,还有一个容器的钥匙,让容器独立于其层次级别获取所有孩子。

With this pseudo code (in the case of all entities are created, not updated)用这个伪代码(在所有实体都被创建的情况下,没有更新)

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

Problem with this code, is that only the rootchild will have the FK for the container set.此代码的问题在于,只有 rootchild 具有容器集的 FK。 I also tried to add the children to they child parent AND the container:我还尝试将孩子添加到他们的孩子父母和容器中:

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

I have the same problem while updating an existing container with new children.我在用新孩子更新现有容器时遇到同样的问题。 I set all the children with the already existing key of the parent, but when SaveChanges is called the key is not saved, its reverted to null.我使用父项已经存在的键设置了所有子项,但是当调用 SaveChanges 时,该键没有保存,它恢复为 null。

I fixed it by doing all this in 2 steps, saving once and then getting all the newly created children and updating them with the parent key, the calling SaveChanges again.我通过分两步完成所有这些来修复它,保存一次,然后获取所有新创建的子项并使用父键更新它们,再次调用 SaveChanges。

I have a feeling I'm missing something, that I should not need to save twice.我有一种感觉,我错过了一些东西,我不需要保存两次。

The number or frequence of SaveChange calls have no implication on anything, not on performance or so. SaveChange 调用的数量或频率对任何事情都没有影响,对性能等没有影响。 So why do you want to minimize it ?那么为什么要最小化它呢?

Actually, storing such a self referencing table with one SaveChanges is not possible, cause the ID of an new entity, is generated, when it is saved.实际上,用一个 SaveChanges 存储这样一个自引用表是不可能的,因为在保存时会生成一个新实体的 ID。 So you first need to save it, and then you get the ID, that you can store in another entity.因此,您首先需要保存它,然后获得可以存储在另一个实体中的 ID。 This might require further update-Commands, to the entity you just stored.这可能需要对您刚刚存储的实体进行进一步的更新命令。

You have two chances to solve this.你有两次机会来解决这个问题。

1) manually generated ID's, handle it all yourself and you know the ID before your store it. 1) 手动生成的 ID,自己处理,并且在存储之前知道 ID。

2) In case you have no circularity in your dependency, so a perfect tree structure, you save the items top-down, level by level. 2)如果您的依赖项中没有循环性,那么完美的树结构,您可以自上而下地逐级保存项目。 I assume you have the childs having a reference to it's parents, so the root has no reference to any other items, you save that first, than the 1st level children, and so on.我假设你有孩子有参考它的父母,所以根没有参考任何其他项目,你首先保存它,而不是第一级孩子,依此类推。

This requires multiple SaveChanges, but this is not a disadvantage.这需要多个 SaveChanges,但这不是缺点。 It is one Insert-SQL-Command per entity anyway, no matter if you do it in 1 SaveChanges or in 100 SaveChanges.无论如何,每个实体都是一个 Insert-SQL-Command,无论您是在 1 SaveChanges 中还是在 100 SaveChanges 中执行此操作。

Both solutions avoid "Update" Commands to the entities, they do Inserts only.这两种解决方案都避免了对实体的“更新”命令,它们只执行插入。

Entity Framework could actually find out this dependencies itself and create an order for new entities to insert, but this is not implemented today, or not perfect, especially on self-referenced tables.实体框架实际上可以自己找出这种依赖关系并创建新实体插入的顺序,但这在今天没有实现,或者并不完美,尤其是在自引用表上。 The order of saving items is kind of random.保存项目的顺序是随机的。 So you have to enforce the order with intermediate SaveChanges.因此,您必须使用中间 SaveChanges 强制执行订单。

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

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