gpt4 book ai didi

c# - EntityCollection 与 List 上的 Except()

转载 作者:行者123 更新时间:2023-11-30 17:58:39 25 4
gpt4 key购买 nike

使用 EntityFramework 4。我有一个 EntityCollection<SomeEntity> currentEntities有 ~500k 个实体和一个 List<SomeEntity> importedEntities也有 ~500k 记录。我想获得 currentEntities 中出现的所有记录的列表importedEntities 中不存在.

调用 currentEntities.Select(x => x.ID).Except(importedEntities.Select(x => x.ID))获取出现记录的唯一 ID 会导致 System.OutOfMemoryException因为它显然将所有实体加载到内存中。

调用 currentEntities.Where(x => !importedEntities.Any(y => y.ID == x.ID))失败 NotSupportedException (“在此上下文中仅支持基本类型('例如 Int32、String 和 Guid')”)。

currentEntities在 SQL Server 2008 R2 数据库上,而 importedEntities在内存中。

这在 L2E 中甚至可能吗?

最佳答案

在内存中的两个“大”整数列表上执行 except 不是重点。如果我执行 Enumerable.Range(0, 500000).Except(Enumerable.Range(500, 500000)).Count(),它会在我说出 OutOfMemoryException 之前返回 500。所以我认为将您的问题减少到整数的 except 应该适合您:

var newIds = importedEntities.Select(x => x.ID).ToArray()
.Except(currentEntities.Select(x => x.ID).ToArray()).ToArray();

因此,只有整数会被加载到内存中,没有实体对象。

现在您可以:

importedEntities.Where(x => newIds.Contains(x.ID))

前提是newIds不要太长。什么太长了? linq 语句生成一个 IN 子句,它可以很容易地包含几千个项目,但如果它长于 10,000 个,您可能应该以 block 的形式处理 ID。

顺便说一句(1)。我在这里假设两个列表都在不同的上下文中,甚至可能在不同的数据库中。但是,如果它们处于相同的上下文中,您可能会成功:

importedEntities.Where(x => !currentEntities.Select(y => y.ID)
.Any(id => id == x.ID))

这会产生一个 NOT EXISTS sql 查询。如果有“许多”新项目,您可能仍会遇到 OutOfMemoryException。如果是这样,您可以使用分页机制(Skip - Take)以 block 的形式处理新项目。

顺便说一下 (2),我调换了 currentEntities 和 importedEntities,因为我假设你对新导入的项目感兴趣,如果我错了请撤消。

关于c# - EntityCollection 与 List 上的 Except(),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12048945/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com