此问题与a previous question of mine
有关这是我目前的代码
IEnumerable<Shape> Get()
{
while(//get implementation
yield return new Shape(//...
}
void Insert()
{
var actual = Get();
using (var db = new DataClassesDataContext())
{
db.Shapes.InsertAllOnSubmit(actual);
db.SubmitChanges();
}
}
我的内存溢出,因为IEnumerable太大了。我该如何预防?
答案 0 :(得分:3)
一种选择是将其分成多个批次。创建Shape
个对象的临时缓冲区,迭代直到填充或从枚举器中用完,然后执行InsertBatchOnSubmit
。
答案 1 :(得分:3)
尝试使用InsertOnSubmit而不是InsertAllOnSubmit。然后像Erich说的那样以适当的间隔提交。
或者,如果你想分批进行,例如5,尝试Handcraftsman's或dtb's解决方案获取IEnumerable的IEnumerable。例如,使用dtb的Chunk:
var actual = Get();
using (var db = new DataClassesDataContext())
{
foreach(var batch in actual.Chunk(5))
{
db.Shapes.InsertAllOnSubmit(batch);
db.SubmitChanges();
}
}
答案 2 :(得分:2)
使用以下扩展方法将输入分解为适当大小的子集
public static class IEnumerableExtensions
{
public static IEnumerable<List<T>> InSetsOf<T>(this IEnumerable<T> source, int max)
{
List<T> toReturn = new List<T>();
foreach(var item in source)
{
toReturn.Add(item);
if (toReturn.Count == max)
{
yield return toReturn;
toReturn = new List<T>();
}
}
if (toReturn.Any())
{
yield return toReturn;
}
}
}
然后保留子集
void Insert()
{
var actual = Get();
using (var db = new DataClassesDataContext())
{
foreach (var set in actual.InSetsOf(5))
{
db.Shapes.InsertAllOnSubmit(set);
db.SubmitChanges();
}
}
}
您可能还会在InsertOnSubmit()和InsertAllOnSubmit()上找到this MSDN article有用。
答案 3 :(得分:1)
要获得从IEnumerable获取批量项目的简洁方法,请参阅:
C#: Cleanest way to divide a string array into N instances N items long
更新:不好,适用于阵列。如果我有一段时间以后没有其他人提供过什么,我会把它写出来......