遵循another SO question中的建议我试图通过将保存操作拆分为多批X条记录来优化一个处理数千条记录的保存(仅插入)操作。当然,我希望这些操作成为单个交易的一部分。
我们正在使用 EF6数据库优先模型。
MSDN上有一篇关于transactions in EF6 and onwards的文章,其中介绍了如何打开连接并自行启动事务,将连接传递给DbContext
构造函数并随后调用UseTransaction
。
但是,这似乎不适用于数据库优先 - 它不断调用DbContext.OnModelCreating
,而UnintentionalCodeFirstException
又会引发using (var conn = new SqlConnection("..."))
using (var context = new BloggingContext(conn, contextOwnsConnection: false))
{
context.Blogs.Add(blog); // invokes ModelCreating and fails.
context.SaveChanges(); // never gets this far
}
。
即使没有交易它也不起作用。例如:
EntityConnection
该异常实际上建议提供using (var sourceContext = new BloggingContext())
{
using (var anotherContext = new BloggingContext(
sourceContext.Database.Connection, // supply existing EntityConnection
contextOwnsConnection: false))
{
context.Blogs.Add(blog); // still fails.
context.SaveChanges(); // never gets this far
}
}
,所以我尝试了以下内容:
TransactionScope
使用foreach (List<Blog> blogBatch in blogBatches)
{
using (var context = new BloggingContext())
{
context.Configuration.AutoDetectChangesEnabled = false;
context.Blogs.AddRange(blogBatch);
context.SaveChanges();
}
}
是另一种选择,但不幸的是,由于打开了多个连接,因此不可避免地会升级到MSDTC,这不是一种选择。
以下是我尝试优化操作的简化版本。如何使用Database First将每个批次新增的上下文包含在单个事务中?
{{1}}
编辑:发现似乎处理相同问题的this question,但仍然没有有用的答案。