【问题标题】:BreezeJS: Retrieving large number of records via executequery() == System.OutOfMemoryExceptionBreezeJS:通过 executequery() == System.OutOfMemoryException 检索大量记录
【发布时间】:2013-12-11 00:49:55
【问题描述】:

如果调用 executequery() 会返回大量(例如超过 625,000 条)记录,是否会出现 System.OutOfMemoryException?

使用 take() 可以正常工作,例如

var query = breeze.EntityQuery
    .from("Biography")
    .select("ENTITY_ID, NAME, NICKNAME")
    .where("VAL1","==","AL")
    .orderBy("ENTITY_ID")
    .take(1000);

但是,询问所有记录会导致 System.OutOfMemoryException 错误。

var query = breeze.EntityQuery
    .from("Biography")
    .select("ENTITY_ID, NAME, NICKNAME")
    .where("VAL1","==","AL")
    .orderBy("ENTITY_ID");

运行等效的 SQL 大约需要 5 秒才能成功完成。

【问题讨论】:

  • 你有什么问题?
  • 当遇到 System.OutOfMemoryException 时,将使用 skip() 和 take() 的多个查询的结果组合起来的最佳解决方案是什么?

标签: .net entity-framework breeze entity-framework-6


【解决方案1】:

我并不感到惊讶。

为了清楚起见,您正试图通过网络传输超过 625,000 条记录,然后从中创建实体。服务器上的查询可能非常快,但是这些记录中的每一个都需要序列化为 json,通过网络发送,然后重新构成一个实体。即使使用最好的实现,这些操作也可能既耗时又占用大量数据。

因此,您有一些选择可以减少内存占用和操作所花费的时间。

  1. 使用 take(根据您的示例)
  2. 使用 EntityQuery.noTracking 选项。这会跳过将序列化记录转换为“真实”实体的步骤。如果您以后需要“真实”实体,您可以根据需要有选择地将它们添加到 EntityManager。

【讨论】:

  • 我结合了这两个选项并将以下内容放在查询变量赋值的末尾:take(500000).noTracking();这可行,但是超过 500000 会导致相同的内存不足异常。我想我会尝试多次查询,使用 skip() 和 take(),每次都将记录添加到数组中——除非有其他方法。有什么更好的主意吗?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-10-26
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多