c# - 在多重限制下检索大量记录,不会导致内存不足异常

标签 c# database linq dynamics-crm

我有以下情况:

  1. 有两种相关的类型。对于这个问题,我将使用以下简单类型:

    public class Person
    {
         public Guid Id {get; set;}
         public int status {get; set;}
    }
    
    public class Account
    {
         public Guid AccountId {get; set;}
         public decimal Amount { get; set; }
         public Guid PersonId { get; set; }
    }
    

    所以那个Person可能有多个 Account s(即多个 Account s 将引用相同的 PersonId )。

  2. 在我们的数据库中,有几万人,平均每个人有5-10个账户。

  3. 我需要检索每个人的帐户,假设他们满足特定要求。之后,我需要查看此人的所有帐户是否一起满足另一个条件。

    在这个例子中,假设我需要 amount < 100 的每个帐户,并且在检索到一个人的帐户后,我需要检查他们的总和是否大于 1000。

  4. 使用 LINQ 查询是可取的,但不能使用 group-by-into 来完成关键字,因为 Linq-Provider (LINQ-to-CRM) 不支持它。

  5. 此外,执行以下简单的 LINQ 查询来实现 list 3 的要求也是不可能的(请阅读内联评论):

    var query = from p in personList
                join a in accountList on p.Id equals a.PersonId
                where a.Amount < 100
                select a;
    var groups = query.GroupBy(a => a.PersonId);
    // and now, run in bulks on x groups 
    // (let x be the groups amount that won't cause an out-of-memory exception)
    

    不可能有两个原因:

    一个。 Linq-Provider 强制调用 ToList()使用前 GroupBy() .

    尝试实际调用 ToList()使用前 GroupBy()结果是 内存不足异常 - 因为有数以万计的帐户。

  6. 出于效率原因,我不想执行以下操作,因为这意味着数万次检索:

    一个。检索所有人。

    遍历它们并在每次迭代中检索每个人的帐户。

会很高兴有有效的想法。

最佳答案

我建议通过 PersonId 对查询进行排序,通过 AsEnumerable() 切换到 LINQ to Objects(从而执行它,但不会在内存中实现整个结果集,例如ToList() 调用),然后使用 GroupAdjacent方法来自 MoreLINQ包裹:

This method is implemented by using deferred execution and streams the groupings. The grouping elements, however, are buffered. Each grouping is therefore yielded as soon as it is complete and before the next grouping occurs.

var query = from p in personList
            join a in accountList on p.Id equals a.PersonId
            where a.Amount < 100
            orderby a.PersonId
            select a;
var groups = query.AsEnumerable()
    .GroupAdjacent(a => a.PersonId)
    .Where(g => g.Sum(a => a.Amount) > 1000);

AsEnumerable() 技巧肯定适用于 EF 查询提供程序。它是否与 LINQ to CRM 提供程序一起工作实际上取决于提供程序如何实现 GetEnumerator() 方法 - 如果它试图缓冲整个查询结果,那么您就不走运了。

关于c# - 在多重限制下检索大量记录,不会导致内存不足异常,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44892308/

相关文章:

c# - Asp.net:如何在成员(member)数据库中添加额外的用户详细信息?

c# - REST 服务代理与 WCF SOAP 代理的性能对比

database - 从 Application.cfc 访问变量

sql - Bigquery 活跃用户计数不准确(谷歌分析)

java - 如何使用java从Mongodb集合中检索数组列表的元素?

linq - 无法使用 LINQ 语法编译我的项目

c# - 将匿名集合放入类中

c# - 这两个 linq 表达式在功能上是否等效?

c# - 应用程序在 Debug模式下运行速度非常慢

c# - WPF 虚线边框控件