Performance 使用EF4.2的批量插入

Performance 使用EF4.2的批量插入,performance,entity-framework-4.1,Performance,Entity Framework 4.1,我们的应用程序存在巨大的性能问题,我们从不同的系统收集数据,并将其保存在数据库中,以便以后生成一些报告 我们使用EntityFramework4.2和DbSet,对于DbSet上的每个实体,是否有比Add方法更好的批量插入方法?因为Add逻辑存在巨大的性能问题 oneThousandCustomers.Foreach(c => context.Customers.Add(c)); //This will take a minute context.SaveChanges(); //This

我们的应用程序存在巨大的性能问题,我们从不同的系统收集数据,并将其保存在数据库中,以便以后生成一些报告

我们使用EntityFramework4.2和DbSet,对于DbSet上的每个实体,是否有比Add方法更好的批量插入方法?因为Add逻辑存在巨大的性能问题

oneThousandCustomers.Foreach(c => context.Customers.Add(c)); //This will take a minute
context.SaveChanges(); //This takes under a second

我猜add方法正在做大量的查找等工作,但我只想批量插入这些数据。有可能吗?

您可以使用对实体集合执行SqlBulkCopy,这将提高应用程序中输入链接描述的性能。

您可以使用对实体集合执行SqlBulkCopy,这将提高应用程序中输入链接描述的性能。

好的,因此交易成功这里是EF在场景下做了很多事情,当你把一个项目添加到一个集合中

性能方面真正重要的一点是,它在枚举整个对象图的每个add命令上自动调用DetectChanges()

这意味着,如果当前EF上下文正在跟踪大量项目,这将导致一些非常严重的性能问题

这里有一些提高性能的技巧,作为比较,我可以在1/2秒内插入1000个没有FK的相当简单的实体到EF

  • 确保您正在为查询使用新的EF上下文实例, 这将确保您的更改图很小,因此添加将很简单 相当快
  • DbContext的自动更改检测回合
关闭自动检测更改的代码

context.Configuration.AutoDetectChangesEnabled = false;
禁用AutoDetectChanges时,您需要稍微小心,因为这意味着大部分EF automagic都已关闭,因此您可能会遇到一些奇怪的情况,尤其是在使用导航属性或更新现有实体时。要解决这些问题,请在调用SaveChanges之前调用DetectChanges。这将降低性能,并且简单的添加操作不需要这样做,因此在您的示例中,您可能不需要这样做


这篇MSDN文章谈到了这一点(注意,尽管它的EF 5在4中是相同的)

好的,所以这里的交易是,当你向收藏中添加一个项目时,EF会在场景下做很多事情

性能方面真正重要的一点是,它在枚举整个对象图的每个add命令上自动调用DetectChanges()

这意味着,如果当前EF上下文正在跟踪大量项目,这将导致一些非常严重的性能问题

这里有一些提高性能的技巧,作为比较,我可以在1/2秒内插入1000个没有FK的相当简单的实体到EF

  • 确保您正在为查询使用新的EF上下文实例, 这将确保您的更改图很小,因此添加将很简单 相当快
  • DbContext的自动更改检测回合
关闭自动检测更改的代码

context.Configuration.AutoDetectChangesEnabled = false;
禁用AutoDetectChanges时,您需要稍微小心,因为这意味着大部分EF automagic都已关闭,因此您可能会遇到一些奇怪的情况,尤其是在使用导航属性或更新现有实体时。要解决这些问题,请在调用SaveChanges之前调用DetectChanges。这将降低性能,并且简单的添加操作不需要这样做,因此在您的示例中,您可能不需要这样做


这篇MSDN文章讨论了这一点(注意,尽管它的EF 5在4中是相同的)

我们使用CQRS框架,并且每个请求都注入上下文,更改上下文行为有点危险,因为无法保证在更改上下文行为后,命令逻辑的其他部分不会使用上下文。性能是危险的,并且涉及妥协,如果您希望获得EF的好处,那么您需要面对性能问题,或者手动管理上下文以优化性能。如果你不想这样做,你也想要性能,那么不要使用EF。然而,我对CQR、消息传递、批量导入和EF(用于查询和写入)做了完全相同的事情,它工作得很好。我们选择这个,因为将现有代码更改为它非常容易。所有的单元测试和场景测试都是绿色的,所以看起来很正常!谢谢我们使用CQRS框架,每个请求都会注入上下文,更改上下文行为有点危险,因为无法保证在更改上下文行为后,命令逻辑的其他部分不会使用上下文。性能是危险的,涉及到妥协,如果您希望获得EF的好处,那么您需要面对性能问题,或者手动管理上下文以优化性能。如果你不想这样做,你也想要性能,那么不要使用EF。然而,我对CQR、消息传递、批量导入和EF(用于查询和写入)做了完全相同的事情,它工作得很好。我们选择这个,因为将现有代码更改为它非常容易。所有的单元测试和场景测试都是绿色的,所以看起来很正常!谢谢