如何使用一个IEnumerable时,能够防止内存溢出 和LINQ到SQL?(How to p

2019-06-23 23:55发布

这个问题关系到我的前面的问题

这是我当前的代码

 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的太大。 我该如何预防呢?

Answer 1:

尝试使用InsertOnSubmit而非InsertAllOnSubmit 。 然后提交在适当的间隔,如埃里希说。

或者,如果你想要做它在如5批次,尽量Handcraftsman的或DTB的解决方案获得了IEnumerable的IEnumerable的的。 例如,与DTB的程序块。

   var actual = Get();
   using (var db = new DataClassesDataContext())
   {
       foreach(var batch in actual.Chunk(5))
       {
         db.Shapes.InsertAllOnSubmit(batch);
         db.SubmitChanges();
       }
   }


Answer 2:

一种选择是将它分解成多个批次。 创建的临时缓冲Shape的物体,迭代,直到您填写或将其从枚举跑出来,然后做一个InsertBatchOnSubmit



Answer 3:

使用下面的扩展方法打破输入到适当大小的子集

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

您可能还会发现这个MSDN文章 VS InsertAllOnSubmit上InsertOnSubmit()()是有用的。



Answer 4:

对于一个巧妙的方法,从IEnumerable得到物品的批次,看到这一点:

C#:以分割字符串数组成N个实例N项长干净的方式

更新:不好,那就阵列工作。 如果我以后有一段时间了,并没有其他人提供的东西,我就写了...



文章来源: How to prevent memory overflow when using an IEnumerable and Linq-To-Sql?