实体框架插入 - 大对象性能

时间:2015-01-14 14:14:37

标签: entity-framework entity-framework-6 bulkinsert

我有一个非常简单的架构,其中包含多层关系。例如,模式看起来像这样

  

OFFICE表有一个建筑物清单,一个自助餐厅列表,一个清单   CoffeeShops每个建筑物都有一个楼层列表。每个楼层都可以   有一个房间列表等。

dbCcontext.Offices.Add(well);
dbContext.SaveChanges()

在某些情况下,我最终得到一个拥有1000个建筑物的Office实体,每个建筑物可以有1000个楼层等。当我有这样的Office对象并尝试使用DbContext.Add和{将其插入数据库时{1}},EF大约需要4秒钟才能插入。我使用EF profiler查看SQL语句,似乎有超过2000个单独的SaveChanges()语句。

个人是否插入了缓慢插入的原因,如果是,那么我的替代方案是什么?

我正在使用Entity Framework 6(代码优先)

1 个答案:

答案 0 :(得分:0)

有两个部分可能会遇到一些性能问题。

  • 添加到ChangeTracker
  • INSERT到数据库

添加到ChangeTracker

我在此假设您遇到了一些性能问题,但首先要检查的是验证是否存在性能问题。

  

OFFICE表有一个建筑物列表,一个自助餐厅列表,一个CoffeeShops列表每个建筑物都有一个楼层列表。每层楼都有房间清单等。

当您添加一个具有大量相关实体并且还具有相关实体(必须非常高!)的实体时,会出现一个问题,即DetectChanges如何工作。它会受到一些表现的影响。

使用AddRange按顺序添加:

  • 地面
  • 建筑
  • 办公室

(Child to parent而不是parent)

可能会带来一些性能提升。你有更多的相关实体,这个技术将变得更好。您必须拥有数千个实体才能看到差异。

代码比简单Offices.Add更长,但我们已经与具有类似方案的客户端(拥有超过10万个实体)合作,并且性能提高了50倍以上!

INSERT到数据库

在您的情况下,您报告超过2000个单独插入,这意味着2000数据库往返。提高性能的唯一方法是减少所需的数据库往返次数。

免责声明:我是该项目的所有者Entity Framework Extensions

此库不是免费的,但会为您的DbContext添加批量操作方法扩展程序:

  • 批量保存更改
  • 批量插入
  • 批量删除
  • 批量更新
  • 批量合并

只需要几次数据库往返,可能会使性能提高25倍以上!

实施例

// Easy to use
context.BulkSaveChanges();

// Easy to customize
context.BulkSaveChanges(bulk => bulk.BatchSize = 100);

// Perform Bulk Operations
context.BulkDelete(customers);
context.BulkInsert(customers);
context.BulkUpdate(customers);

// Customize Bulk Operations
context.BulkInsert(customers, options => {
   options => options.IncludeGraph = true;
});
context.BulkMerge(customers, options => {
   options.ColumnPrimaryKeyExpression = 
        customer => customer.Code;
});