实体框架 - 有效地删除所有子实体而不加载它们

Posted

技术标签:

【中文标题】实体框架 - 有效地删除所有子实体而不加载它们【英文标题】:Entity Framework - Efficiently Delete All Child Entities Without Loading Them 【发布时间】:2014-08-21 07:27:54 【问题描述】:

我是 Entity Framework 的新手,所以如果我的逻辑有偏差,请原谅我/这已经是工作的方式,但我正在开发一个应用程序,其中:

    我将父信息存储在一个表中,主键 = ParentId 对于每个 ParentId,我将数千条记录存储在一个子表中,在 ParentId 上具有一对多外键关系。

因此,如果父母的信息发生变化(这种情况经常发生),我想做的是让我的程序执行相当于:

DELETE FROM ChildTable WHERE ParentId = 'xx'

在使用相同 ParentId 的新/更新值更新子表之前。


据我所见,我会这样做:

使用ctx.Database.ExecuteSqlCommand() kind-of-concept 输入实际的 SQL 命令 在某种程度上,实际上循环遍历子元素并将它们设置为在更新数据库上下文之前删除(这似乎效率非常低,因为我猜它必须将它们从数据库中拉出才能这样做,我想做的就是将它们全部删除)。

在 EF 中以最有效的方式执行此操作的正确方法是什么?

【问题讨论】:

可能重复***.com/questions/2519866/… @Stilgar,感谢您指出这一点,我确实看到了这个问题,但我仍然感到困惑(也许我需要更多的解释)这是否需要循环遍历所有子元素或不......那部分对我来说仍然没有意义...... 如果您担心效率,只需编写存储过程或原始 SQL。 EF 对此有很好的支持。 根据您的陈述我是全新的通常用于此的术语是批量删除。但你不会知道,直到你知道这一点。考虑到这一点,您可能会找到更好的结果,但可以节省一些时间。这是一个很好的 SO ***.com/questions/869209/… 。为了节省您更多的时间,这里有一个不错的库,它为您构建了许多功能。它也有关于如何使用它的很好的文档。它使用 Linq 仅供参考。 github.com/loresoft/EntityFramework.Extended 关于最有效的方式也是您的观点,这是您可能感兴趣的扩展库的引用“实体框架的当前限制是为了更新或删除一个实体,您必须先将其检索到内存中。现在在大多数情况下,这很好。但是,在某些情况下,性能会受到影响。此外,对于单次删除,必须先检索对象,然后才能将其删除,这需要两个调用数据库。批量更新和删除消除了在修改实体之前检索和加载实体的需要。" 【参考方案1】:

对于简单的批量删除,我通常直接发出一条 SQL 语句。即:

context.Database
    .ExecuteSqlCommand("DELETE FROM TheTable Where MyColumn = 0", parameter);

如果您需要更高级的支持,那么使用 Ef Extended 的另一个答案也可以。这只是一种不需要额外依赖的简单查询的简单方法。

但是请注意,执行此操作时,DbContext 的内部缓存可能会与您的数据库不同步。因此,在执行完这样的命令后,最好不要再执行任何与对象相关的查询,直到您更新了新的上下文。

【讨论】:

非常感谢,Erik,我在想这是一种方法,只是对 EF 来说太新了,我希望他们已经编写了一些看起来非常必要的东西......而且特别感谢关于不使用相同上下文的提示......我肯定会非常方便! 还有一个问题 - 根据您的知识,您更愿意按照自己的方式编写,还是存储过程会更好? @JohnBus​​tos - 存储过程对于这么简单的事情几乎没有价值,除非您的公司要求您使用它们。【参考方案2】:

批量删除和任何批量更新语句是对默认实体框架行为的限制。一种解决方法是使用允许这些批量命令的扩展库,而无需将实体拉入内存来删除它们。

https://github.com/loresoft/EntityFramework.Extended。它还在那个网站上有很好的文档,关于如何使用各种功能。

【讨论】:

谢谢!!! - 只是好奇,EF6 中没有任何内置功能可以做到这一点,对吗?? 不是我所知道的,快速谷歌搜索并没有发现任何问题。这意味着可能不是。我可以找到说这超出了 EF 试图做的事情的范围,即严格的对象映射。希望对您有所帮助。 如果您因为不想拥有第三方库而询问,FWIW 您可以自己编写这些扩展。 cmets 中的 SO 问题有一个次要答案,显示了批量删除的示例代码。 Madullah,我非常感谢你......我总是更喜欢使用尽可能少的“添加”,所以如果 EF6 已经有这样的功能,我会拥有更喜欢使用它,但是那个库看起来干净高效,那为什么不呢,对吧? :) 我仍在考虑编写一个存储过程并从代码中调用它,但是这个库似乎是一个很好的工具!

以上是关于实体框架 - 有效地删除所有子实体而不加载它们的主要内容,如果未能解决你的问题,请参考以下文章

为啥实体框架核心加载实体的关系而不添加包含

实体框架在不询问的情况下填充子实体[重复]

实体框架 4 代码优先的优缺点 [关闭]

使用实体框架删除大量项目[重复]

最有效的实体框架代码第一方法展平/投影具有特定子实体的父实体

试图理解删除实体框架中的子实体