尝试在LINQ查询上使用ToDictionary时出现System.OutOfMemoryException

时间:2014-06-12 20:27:05

标签: c# linq exception dictionary

我正在尝试从包含600万条记录的销售表中填充字典对象。这是因为原始linq查询超时。我正在将3或4个表加入到销售表中,这太多了,而且超时了。我以为我可以在内存中获取sales表来防止sql server的超时。

我的代码是:

var sales = dc.Sales
    .Where(c => c.Active == true)
    .Select(s => s)
    .ToDictionary(s => s.Id, s => s);

有没有人知道如何在不引起内存不足异常的情况下填充我的字典对象?

3 个答案:

答案 0 :(得分:2)

这个问题暗示了对数据库查询工作原理的严重误解。通常,当查询超时时,您必须限制要提取的数据。如果你真的需要提取这么多数据(我认为这是业务需求中的错误),那么你应该分批提取它们。

  

我们通常使用linq to sql

Linq-to-SQL已经折旧多年了。它在创建可用的SQL查询方面几乎无能为力。这可能是你获得超时的原因。我认为LINQ-to-SQL不仅是一个糟糕的选择,而且在你准备爆炸的软件中相当于炸弹的直接风险。您应该使用LINQ-to-Entities移动到Entity Framework,或者使用手工制作的SQL。这暗示了第二个问题:

  

我们将数据加载到字典中以加速应用程序并将字典加入并提取数据

我从来没有听过任何人会使用这种方法或认为它可以接受使用。 SQL可以轻松快速地完成此任务。如果你的团队真的认为这是做事的方式,那么就需要认真研究SQL。

答案 1 :(得分:0)

感谢大家的反馈。我发现导致内存不足异常的原因。我决定不使用字典,因为它不会起作用。我去了sql server并复制了我的linq查询并运行它,只返回了30,000条记录。所以我知道linq查询不会导致内存不足。我的原始查询只是使用一些.Where()子句对数据库进行简单查找。事实证明我在使用30,000条记录填充的集合上执行.Distinct(),这导致了内存不足异常。我删除了linq查询上的.Distinct()调用并修复了它。内存不足异常是有道理的,因为它试图处理集合中的30,000条记录并将它们区分开来,而且只需要进行比较。

答案 2 :(得分:-1)

我建议使用ctx.Configuration.LazyLoadingEnabled = true;启用延迟加载,然后在需要数据时,将自己加载所需的实体。然后,如果您不关闭上下文并再次打开,则加载的实体可以保留在上下文中并重新使用。 我已尝试使用100000个实体的程序,并使用延迟加载允许立即打开所需的对象。