我正在寻找插入实体框架的最快方法。
我之所以问这个问题,是因为您有一个活动的TransactionScope,并且插入量很大(4000+)。它可能会持续超过10分钟(事务的默认超时),这将导致事务不完整。
我正在寻找插入实体框架的最快方法。
我之所以问这个问题,是因为您有一个活动的TransactionScope,并且插入量很大(4000+)。它可能会持续超过10分钟(事务的默认超时),这将导致事务不完整。
当前回答
另一种选择是使用Nuget提供的SqlBulkTools。它非常容易使用,并且具有一些强大的功能。
例子:
var bulk = new BulkOperations();
var books = GetBooks();
using (TransactionScope trans = new TransactionScope())
{
using (SqlConnection conn = new SqlConnection(ConfigurationManager
.ConnectionStrings["SqlBulkToolsTest"].ConnectionString))
{
bulk.Setup<Book>()
.ForCollection(books)
.WithTable("Books")
.AddAllColumns()
.BulkInsert()
.Commit(conn);
}
trans.Complete();
}
有关更多示例和高级用法,请参阅文档。免责声明:我是这个图书馆的作者,任何观点都是我自己的观点。
其他回答
秘密是插入到相同的空白暂存表中。插件快速发光。然后在主大表中运行一个单独的插入。然后截断临时表,为下一批做好准备。
ie.
insert into some_staging_table using Entity Framework.
-- Single insert into main table (this could be a tiny stored proc call)
insert into some_main_already_large_table (columns...)
select (columns...) from some_staging_table
truncate table some_staging_table
我将推荐这篇关于如何使用EF进行批量插入的文章。
实体框架和慢速批量INSERT
他探索了这些领域并比较了绩效:
默认EF(57分钟完成添加30000条记录)替换为ADO.NET代码(对于相同的30000,25秒)上下文膨胀-通过为每个工作单元使用一个新的上下文来保持活动的上下文图较小(相同的30000个插入需要33秒)大列表-关闭AutoDetectChangesEnabled(将时间缩短至约20秒)批处理(最短16秒)DbTable.AddRange()-(性能在12范围内)
最快的方法是使用批量插入扩展,这是我开发的
注:这是一种商业产品,不是免费的
它使用SqlBulkCopy和自定义数据读取器来获得最大性能。因此,它比使用常规插入或AddRange快20倍以上
用法非常简单
context.BulkInsert(hugeAmountOfEntities);
据我所知,EntityFramework中没有BulkInsert来提高大型插件的性能。
在这种情况下,您可以使用ADO.net中的SqlBulkCopy来解决问题
正如其他人所说,如果您想要真正好的插入性能,SqlBulkCopy是一种实现方法。
它的实现有点麻烦,但有一些库可以帮助您实现它。有一些库,但这次我将无耻地使用我自己的库:https://github.com/MikaelEliasson/EntityFramework.Utilities#batch-插入实体
您需要的唯一代码是:
using (var db = new YourDbContext())
{
EFBatchOperation.For(db, db.BlogPosts).InsertAll(list);
}
那么它快多少?很难说,因为这取决于许多因素,计算机性能、网络、对象大小等。我所做的性能测试表明,如果您像其他答案中提到的那样优化EF配置,则可以在10秒左右以标准方式在本地主机上插入25k个实体。使用EFUtilities,大约需要300毫秒。更有趣的是,我使用这种方法在不到15秒内保存了大约300万个实体,平均每秒大约200万个实体。
当然,一个问题是若需要插入相关数据。这可以使用上述方法在sql server中高效地完成,但它需要您有一个Id生成策略,允许您在应用程序代码中为父级生成Id,以便您可以设置外键。这可以使用GUID或类似HiLo id生成的方法来完成。