首先获取特定数量的数组然后处理

时间:2014-07-21 14:55:57

标签: c# arrays

我的代码如下:

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();
}

我在这里可以看到的问题是如何删除newReferencesID上的前500个referencesID?因为如果我在第一次循环后没有删除前500,它将继续添加referencesID。

3 个答案:

答案 0 :(得分:2)

您是否只想更新referencesIDs值?像这样的东西?:

referencesIDs = referencesIDs.Skip(500);

然后,当您下次.Take(500)上的referencesIDs时,它会获得下一个 500的值。

相反,如果不更新referencesIDs变量,则可以在循环中包含Skip。像这样:

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

答案 1 :(得分:2)

我的第一选择是修复服务,如果您有权访问它。特定于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();

答案 2 :(得分:1)

如果您想要一种将列表拆分为块的一般方法,可以使用以下内容:

/// <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();