使用EF进行批量插入

时间:2014-10-08 07:50:53

标签: c# entity-framework database-performance

我需要使用C#和EF(使用.NET 3.5)在数据库中插入一些对象(大约400万个)。我添加对象的方法是for:

 private DBModelContainer AddToContext(DBModelContainer db, tblMyTable item, int count)
        {
            db.AddTottblMyTable (item);
            if ((count % 10000== 0) || (count == this.toGenerate))
            {
                try
                {
                    db.SaveChanges();
                }
                catch (Exception e)
                {
                    Console.WriteLine(e.StackTrace);
                }
            }
            return db;
        }

如何从上下文对象中分离添加的对象(类型为tblMyTable)?我不需要它们供以后使用,当添加超过300000个对象时,db save(db.SaveChanges())之间的执行时间会大大增加。

此致

3 个答案:

答案 0 :(得分:2)

AFAK EF不直接支持BulkInsert,因此手动执行此操作将非常繁琐。

尝试考虑EntityFramework.BulkInsert

using (var ctx = GetContext())
{
  using (var transactionScope = new TransactionScope())
  {
    // some stuff in dbcontext

    ctx.BulkInsert(entities);

    ctx.SaveChanges();
    transactionScope.Complete();
  }
}

答案 1 :(得分:2)

实体框架可能不是此类操作的最佳工具。使用普通的ADO.Net,一些存储过程可能会更好......但是如果你必须使用它,这里有一些建议:

  • 通过为每个上下文使用新的上下文来保持活动的Context Graph较小 工作单元
  • 关闭AutoDetechChangesEnabled - context.Configuration.AutoDetectChangesEnabled = false;
  • 在循环中批处理,定期调用SaveChanges

修改

    using(var db = new DBModelContainer())
    {
       db.tblMyTable.MergeOption = MergeOption.NoTracking;
       // Narrow the scope of your db context
       db.AddTottblMyTable (item);
       db.SaveChanges();
    }

建议不要使用长时间运行的db上下文,因此请考虑重构Add方法,以避免尝试重用相同的上下文。

请参阅Rick Strahl's post on bulk inserts for more details

答案 2 :(得分:0)

您可以尝试单位工作,不要在每个记录插页上保存上下文(SaveChanges),但保存在结尾