EF SaveChanges优化?

时间:2013-03-14 12:57:01

标签: c# entity-framework

为什么DbContext ctx在每个SaveChanges()之后处理得更快?

第一个样本:

var ctx = new DomainContext(); 
foreach (var item in deals)
        {
            DealsOfReutersAddition newDealAddition =
                        new DealsOfReutersAddition
                        {
                            DealsOfReutersId = item.DealsOfReutersId,
                            DealDate = DateTime.Parse(item.DateConfirmed ?? "01 01 01", new CultureInfo("en-US")),
                        };
            ctx.DealsOfReutersAdditions.Add(newDealAddition);
            ctx.SaveChanges();
        }

ctx.Dispose();

第二个样本:

foreach (var item in deals)
        {
            DealsOfReutersAddition newDealAddition =
                        new DealsOfReutersAddition
                        {
                            DealsOfReutersId = item.DealsOfReutersId,
                            DealDate = DateTime.Parse(item.DateConfirmed ?? "01 01 01", new CultureInfo("en-US")),
                        };
            var ctx = new DomainContext(); 
            ctx.DealsOfReutersAdditions.Add(newDealAddition);
            ctx.SaveChanges();
            ctx.Dispose();
        }

在1000行中,第二个样本估计为8秒,首先是140秒。 有没有办法清理ctx而不是重新创建?

1 个答案:

答案 0 :(得分:3)

根据@JensKloster在评论中所说的话,你肯定不想在循环中每次都调用SaveChanges。但我实际上会抵制把它放在循环之外的诱惑。随着上下文跟踪的对象数量越来越多,将会耗尽更多的内存,并且会使保存速度逐渐变慢。

我的解决方案是,在循环中设置一个运行计数器,以确定何时进行保存:

int numberOfRecords = 0;
using(var ctx = new DomainContext())
{
  foreach (var item in deals)
          {
              DealsOfReutersAddition newDealAddition =
                          new DealsOfReutersAddition
                          {
                              DealsOfReutersId = item.DealsOfReutersId,
                              DealDate = DateTime.Parse(item.DateConfirmed ?? "01 01 01", new CultureInfo("en-US")),
                          };

              ctx.DealsOfReutersAdditions.Add(newDealAddition);

              numberOfRecords++;
              if(numberOfRecords % 500 == 0) //Saves after every 500 rows.
              {
                ctx.SaveChanges();
              }
           }
}