c# - 将大量整数加入 LINQ 查询

标签 c# asp.net sql linq linq-to-sql

我的 LINQ 查询返回以下错误: “传入的表格数据流 (TDS) 远程过程调用 (RPC) 协议(protocol)流不正确。此 RPC 请求中提供的参数过多。最大值为 2100”。

我需要做的就是计算所有具有我在列表中的 ID 的出生日期的客户。 我的客户 ID 列表可能很大(数百万条记录)。

这里是查询:

List<int> allClients = GetClientIDs();

int total = context.Clients.Where(x => allClients.Contains(x.ClientID) && x.BirthDate != null).Count();

当查询被这样重写时,

int total = context
    .Clients
    .Count(x => allClients.Contains(x.ClientID) && x.BirthDate != null);

它会导致同样的错误。

还尝试以不同的方式制作它并且它吃掉了所有内存:

List<int> allClients = GetClientIDs();

total = (from x in allClients.AsQueryable()
         join y in context.Clients
         on x equals y.ClientID
         where y.BirthDate != null
         select x).Count();

最佳答案

我们在工作中遇到了同样的问题。问题是 list.Contains() 创建了一个 WHERE column IN (val1, val2, ... valN) 语句,因此您只能使用多少个值可以放在里面事实上,我们最终做的是像您一样分批进行。

不过,我想我可以为您提供一段更简洁、更优雅的代码来完成这项工作。这是一个扩展方法,将添加到您通常使用的其他 Linq 方法中:

public static IEnumerable<IEnumerable<T>> BulkForEach<T>(this IEnumerable<T> list, int size = 1000)
{
    for (int index = 0; index < list.Count() / size + 1; index++)
    {
        IEnumerable<T> returnVal = list.Skip(index * size).Take(size).ToList();
        yield return returnVal;
    }
}

然后你像这样使用它:

foreach (var item in list.BulkForEach())
{
    // Do logic here. item is an IEnumerable<T> (in your case, int)
}  

编辑
或者,如果你愿意,你可以让它像普通的 List.ForEach() 那样工作:

public static void BulkForEach<T>(this IEnumerable<T> list, Action<IEnumerable<T>> action, int size = 1000)
{
    for (int index = 0; index < list.Count() / size + 1; index++)
    {
        IEnumerable<T> returnVal = list.Skip(index * size).Take(size).ToList();
        action.Invoke(returnVal);
    }
}

这样使用:

list.BulkForEach(p => { /* Do logic */ });

关于c# - 将大量整数加入 LINQ 查询,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14673949/

相关文章:

jquery - Bootstrap 3.0 不适用于母版页

mysql - 使用 AND & OR 语句对 MySQL 来说是不是太糟糕了?

sql - 在 Oracle 中使用 sql 查找日期范围中的差距

javascript - 用于查找重复出现的多个非数字字符的正则表达式模式

C# 停止并继续

c# - IIS 的 WCF 服务宿主,spring.net 范围 ="request"

asp.net - 如何切换中继器中 DIV 的可见性?

c# - ASP.NET View 和模型,一个小问题

c# - 运行我的 c# Selenium WebDriver 代码的 NUnit 错误

mysql - Group_Concat 中的元素数