先取特定数量的数组再处理

本文关键字:数组 再处理 | 更新日期: 2023-09-27 18:14:10

下面是下面的代码:

InstanceCollection instances = this.MyService(typeID, referencesIDs);

我这里的问题是当referencesIDs.Count()大于一个特定的计数时,它抛出一个与SQL相关的错误。

建议我多次调用this.MyService,这样它就不会处理很多referencesIDs

怎么做呢?我正在考虑使用像这样的while循环:

while (referencesIDs.Count() != maxCount)
{
    newReferencesIDs = referencesIDs.Take(500).ToArray();
    instances = this.MyService(typeID, newReferencesIDs);
    maxCount += newReferencesIDs.Count();
}

我在这里看到的问题是,我如何删除newReferencesIDs上的前500个referencesid ?因为如果我不删除第一个循环后的前500,它将继续添加referencesid

先取特定数量的数组再处理

您只是想更新referencesIDs值吗?像这样的?:

referencesIDs = referencesIDs.Skip(500);

那么下次在referencesIDs上调用.Take(500)时,它将获得下一个 500个值。

相反,在不更新referencesIDs变量的情况下,可以在循环中包含Skip。像这样:

var pageSize = 500;
var skipCount = 0;
while(...)
{
    newReferencesIDs = referencesIDs.Skip(skipCount).Take(pageSize).ToArray();
    skipCount += pageSize;
    ...
}

我的第一选择是修复服务,如果你可以访问它。特定于SQL的错误可能是数据库配置不完整的结果,或者是服务器上SQL查询写得不好的结果。例如,Oracle将SQL查询中的IN列表默认限制为1000项左右,但是您的Oracle DBA应该能够为您重新配置此限制。或者,服务器端程序员可以重写他们的查询,以避免在一开始就达到这个限制。

如果这不起作用,您可以将列表分割成不会触发错误的最大大小块,对服务器进行多次调用,并在您的端组合实例,如下所示:

InstanceCollection instances = referencesIDs
    .Select((id, index) => new {Id = id, Index = index})
    .GroupBy(p => p.Index / 500) // 500 is the max number of IDs
    .SelectMany(g => this.MyService(typeID, g.Select(item => item.Id).ToArray()))
    .ToList();

如果您想要将列表分成块的通用方法,您可以使用以下命令:

/// <summary>
/// Split a source IEnumerable into smaller (more manageable) lists.
/// </summary>
public static IEnumerable<IList<TSource>> 
    SplitIntoChunks<TSource>(this IEnumerable<TSource> source, int chunkSize)
{
    long i = 1;
    var list = new List<TSource>();
    foreach (var t in source)
    {
        list.Add(t);
        if (i++ % chunkSize == 0)
        {
            yield return list;
            list = new List<TSource>();
        }
    }
    if (list.Count > 0)
        yield return list;
}

然后你可以使用SelectMany来使结果变平:

InstanceCollection instances = referencesIDs
    .SplitIntoChunks(500)
    .SelectMany(chunk => MyService(typeID, chunk))
    .ToList();