带EF的大容量插入件

本文关键字:插入 大容量 EF | 更新日期: 2023-09-27 18:26:02

我需要使用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.SaveChanges())之间的执行时间会显著增加。

问候

带EF的大容量插入件

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

  • 通过为每个对象使用新的上下文来保持活动的上下文图较小工作单位
  • 关闭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();
    }

保持长时间运行的数据库上下文是不可取的,因此请考虑重构Add方法,不要一直试图重用同一上下文。

请参阅Rick Strahl关于批量插入的文章,了解更多详细信息

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

您可以尝试"工作单元",不在每个记录插入时保存上下文(SaveChanges),而是在结束时保存它