我的代码如下:
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。
答案 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();