【问题标题】:Entity Framework 3.5: Saving objects in stages with separate contextsEntity Framework 3.5:在不同的上下文中分阶段保存对象
【发布时间】:2012-01-13 11:12:59
【问题描述】:

在 C# 和 Entity Framework 3.5 中,我有一个包含数百万条记录的上下文。这需要大约 2 GB 的 RAM。只要我打电话给SaveChanges(),它就会开始填满我的 8 GM RAM 并开始交换。

我使用了分析器,结果发现是 SQL 查询占用了内存。

现在我想批量保存,但是遇到了问题。

我有一个Locations 的集合(它又具有东西的集合和子集合)。当我分批拆分它并为每个分配一个新的上下文时,只要我这样做context.AddToOrder(firstBatch)all 批次中的 ALL 位置突然具有实体状态Added,即使他们没有Order。这会导致保存失败,因为 Order -> Location 关系不存在。

当我只将其中的一个子集添加到上下文时,为什么原始集合中的所有对象都获得状态 Added

【问题讨论】:

  • 您确定所有内存都已被应用程序使用吗?或者它可能被 Sql Server 使用。
  • 所有 sql 查询字符串都必须在某处生成,我猜那将是 ram。只保存其中的一部分怎么样,也许使用事务范围。
  • 不是 SQL 服务器,而是另一台机器。以及关于交易范围;这可能是一种可能性,但我最后一次尝试(几周前)时,它需要在服务器上进行很多奇怪的设置,我停止了它。它需要重新启动,我现在无法重新启动服务器。无论如何,在查看活动监视器之后,SQL 确实还没有被执行,而它正在消耗 RAM。
  • 您绝对应该分块保存数据。仅在 RAM 中保存大量数据是不安全的,因为如果您的系统崩溃,任何东西都会丢失。交易应该可以正常工作。
  • 安全不是问题;我从头开始生成这些记录,然后保存它们。

标签: c# entity-framework


【解决方案1】:

我有几百万条记录的上下文。这需要大约 2 GB 的 RAM。

我知道你不会喜欢这个答案,但它很简单。 不要那样做。 EF 尤其是 EFv1 还没有为此做好准备。 EF 甚至不是处理数十 MB 的工具。您必须对此类大数据集使用其他工具,或者将您的更新划分为多个(在您的情况下为数千甚至数百万)小的更改集,每个更改集都使用自己的上下文。

我猜当您致电SaveChanges 时,EF 会尝试发挥其魔力,包括检测实体的变化并准备要执行的语句。可能存在内存泄漏,但由于 GC 也可能存在大量未释放的内存。在这种情况下,与您当前的问题无关。

顺便说一句。 EF 将尝试将您的修改存储在单个事务中。因此,如果您尝试在单个事务中节省 2GB,则可能会出现更多级别的问题。

【讨论】:

  • 那是因为调用 Add 将添加对象图中的所有内容,而不仅仅是单个位置。因此,如果您的位置具有东西的导航属性,那么也会添加东西,并且如果东西具有位置的导航集合,那么也会添加所有这些位置。划分它并不容易。当您已经有 2GB 的互连对象时,它将不起作用。您必须分批处理对象并仅构建该批次中存在的关系。
  • 据我所知,一个位置应该通过“stuff”链接到另一个位置;一个位置,它的“东西”应该是完全独立的。但我会再次检查以确保。
猜你喜欢
  • 2020-07-14
  • 1970-01-01
  • 1970-01-01
  • 2011-03-31
  • 2013-12-25
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多