具有事务管理的实体框架批量插入 - 性能

时间:2018-02-08 06:11:57

标签: c# entity-framework-6

我按照以下链接中的答案提高了批量插入和更新的实体框架的性能。

Improving bulk insert performance in Entity framework

  1. 以1000批次保存更改
  2. 每次保存更改后DbContext对象的重新生成
  3. 我的表现得到了预期的提升。

    但是我要求在执行批量插入时在异常情况下回滚事务。

    当我们重新初始化DbContext对象时,这就成了问题。

    在异常情况下是否有其他方法可以使用相同的设置来使用事务和回滚?

    任何帮助将不胜感激

1 个答案:

答案 0 :(得分:0)

交易

如果要回滚更改,则需要使用事务。

您可以在生成的所有上下文中共享相同的连接。

这是一个小例子:

try
{
    var connection = new SqlConnection("[ConnectionString]");
    var trans = connection.BeginTransaction();

    while (condition)
    {
        using (TestContext context = new TestContext(connection))
        {
             // ...code..
        }
    }

    trans.Commit();
}
catch
{
    // ...code..
}

public class TestContext : DbContext
{
    public TestContext(SqlConnection connection) : base(connection, false)
    {

    }

    // ...code...
}

批量插入

您没有执行BulkInsert。您目前正在修复每次使用DetectChanges方法时调用的Add方法的性能问题。

请参阅:http://entityframework.net/improve-ef-add-performance

如果要插入50,000个实体,则仍然执行50,000次数据库往返, INSANELY 慢。

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

此库是付费库,但您可以真正执行BulkInsert。

只需要几次数据库往返

实施例

// 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;
});

编辑:回复评论

  

拟议的图书馆看起来确实很棒。但是,请您详细说明批量操作的交易管理吗?

当然,

文档:http://entityframework-extensions.net/transaction

BulkSaveChanges

作为SaveChanges,BulkSaveChanges已经保存了内部事务中的所有实体。因此,默认情况下,无需做任何事情。

但是,如果您在实体框架内启动交易,BulkSaveChanges将尊重它并将使用此交易而不是创建内部交易。

var transaction = context.Database.BeginTransaction();
try
{
    context.BulkSaveChanges();
    transaction.Commit();
}
catch
{
    transaction.Rollback();
}

批量操作

批量操作(如BulkInsert,BulkUpdate,BulkDelete)默认情况下不使用事务。这是你的责任。

如果您在实体框架内开始交易,批量操作将尊重它。

var transaction = context.Database.BeginTransaction();
try
{
    context.BulkInsert(list1);
    context.BulkInsert(list2);
    transaction.Commit();
}
catch
{
    transaction.Rollback();
}