SqlBulkCopy和entity framework

我目前的项目包括3个标准层:数据,业务和演示。 我想使用数据实体来满足我的所有数据访问需求。 应用程序的部分function是需要将平面文件中的所有数据复制到数据库中。 该文件不是很大,所以我可以使用SqlBulkCopy。 我在.NET中找到了几篇关于SqlBulkCopy类用法的文章。 但是,所有文章都使用DataTable来来回移动数据。

有没有办法将数据实体与SqlBulkCopy一起使用,还是必须使用DataTables?

您需要将实体转换为IDataReader或DataTable。

有一个小帮助类,旨在帮助: http : //archive.msdn.microsoft.com/LinqEntityDataReader/Release/ProjectReleases.aspx?ReleaseId = 389

编辑:msdn链接坏了,可以在这里找到alt拷贝: https : //github.com/matthewschrager/Repository/blob/master/Repository.EntityFramework/EntityDataReader.cs

然后您可以像这样使用SqlBulkCopy:

var sbCopy= new SqlBulkCopy(connectionString); sbCopy.DestinationTableName = "TableName"; sbCopy.WriteToServer(entitiesList.AsDataReader()); 

我们在使用EF批量插入时尝试并测试了几种方法,最终使用表值参数来获得各种行大小的最佳性能。 我没有数字,但我知道bcp / BULK INSERT与表值参数的性能是一个指导因素。

我们最初使用SqlBulkCopy和一个接受IEnumerable并创建了IDataReader的适配器。 它还为SqlBulkCopy生成了相关的元数据。 这里的优点是导入只是代码。 @davehogan发布的代码用作此基础。

表值参数需要存储过程和数据库中定义的表类型。 如果您正在使用代码优先,则可以执行SQL以将其创建为创建脚本的一部分。 虽然这是更多的工作,但我们发现我们在数据库中获得了更加一致和更快的行吞吐量。

此外,值得考虑不要批量插入主表。 我们使用临时堆表,并在导入数据后向其添加聚簇索引。 然后,我们在临时表和主表之间执行MERGE 。 这样做的好处是在插入时不会锁定主表的索引并提高并发性。 我们倾向于使用此方法插入每个CPU插入的2500行/秒。

如果您想了解更多信息,请与我们联系。

您可以使用Bulk包库。 批量插入1.0.0版本用于具有entity framework> = 6.0.0的项目中。 更多描述可以在下面的链接 – Bulkoperation源代码中找到

对于EFCore,这里是BulkExtensions(Insert,InsertOrUpdate Update,Delete):
链接: https : //github.com/borisdj/EFCore.BulkExtensions
也可以通过Nuget安装

SqlBulkCopy在调用WriteToServer方法时使用IDataReader,因此您应该能够基于IEnumerable的集合实现IDataReader。 这将允许您接受实体集并使用您的IDataReader实现调用SqlBulkCopy。

您可以将数据集视为数据实体的序列化。 不过一般来说,我认为SqlBulkCopy是一个表到表的东西,因此是数据表的原因。

SqlBulkCopy是一种直接的,几乎像字节数组的行数据从客户端到SQL Server的传输。 这是将数据导入SQL Server的最有效方法。

然而,它的表现在于真正的“批量”操作。 数百或数千行不一定足以certificate使用的合理性。 数万到数百万行是SqlBulkCopy的表现将真正闪耀。 而且,最后,我们真正谈论的是将数据传输到服务器

将一组行放入生产数据库表中还有其他重大挑战。 重新索引,重新排序(如果有聚簇索引),外键validation,所有这些事情都会增加插入时间,并且可能是表锁和索引锁定。

此外,TVP数据被写入磁盘(作为临时表数据),然后可以放入表中。 SqlBulkCopy能够直接进入你的表…在这种情况下,性能明显加快,但是,必须平衡并发速度。

我认为总体规则是,如果你有一些行要处理,想想TVP,如果你有几千行,考虑尽可能快地通过SqlBulkCopy将它送到SQL Server。

作为@DaveHogan回答的补充,

现在有了新的库,它们允许使用数据实体而不是DataTable为Entity Framework执行批量插入(使用SqlBulkCopy)。

免责声明 :我是项目entity framework扩展的所有者

该库不是免费的,但可以轻松执行:

  • BulkSaveChanges
  • BulkInsert
  • BulkUpdate
  • BulkDelete
  • BulkMerge

在引擎盖下,使用SqlBulkCopy。 使用扩展方法make比为每个批量插入编码自定义解决方案更容易/更快。

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

表现不佳

对不起,你的表现很差,

确保你没有把时间从一些常见错误中包括忘记JIT编译,使用Add而不是AddRange影响测试性能但与我们的库无关。

大多数人报告在排除所有常见性能基准测试错误时,性能提升了25-50倍。

请参阅: entity framework扩展 – 基准