【问题标题】:Rollback Entity Framework SaveChanges()回滚实体框架 SaveChanges()
【发布时间】:2023-01-29 07:45:03
【问题描述】:

例如,我将每个州的人员数据添加到数据库中(这不是我正在做的,但模型是相同的)。我们有州名单,每个州都有数百万人。因此,最初在代码中,我保存状态以获取状态 ID,然后使用该 ID 批量插入人员数据。

如果在添加人员数据时出现问题,假设第 2000 万条记录抛出一些异常,是否有办法恢复已保存在 PeoplesState 表中的数据?

任何建议都非常感谢..

List <Peoples> PeopleList = new List<Peoples>();
int peopleCounter = 0;

foreach (var stateVal in States)
{
    using (var context = new StateEntities())
    {
        State st = new State();
        st.ID = stateVal.ID;
        st.Name = stateVal.Name;

        context.State.Add(st);
        context.SaveChanges(); 

        if (stateVal.Peoples != null )
        {
            foreach (var _p in stateVal.Peoples)
            {
                Peoples _people = new Peoples();
                _people.Name = _p.Name;
                _people.Age = _P.Age;
                _people.State_ID = stateVal.ID; // Getting state ID from State object as it already saved to DB

                PeopleList.Add(_people)
                peopleCounter++;

                if (peopleCounter == 100000)
                {
                    InsertPeople(PeopleList, context); // does bulk insert when PeopleList reaches 100k
                    PeopleList.Clear();
                    peopleCounter = 0;
                } 
            }
        }
    }
}

private static void InsertPeople(List<Peoples> PeopleList, StateEntities context)
{
    context.Configuration.AutoDetectChangesEnabled = false;
    context.Configuration.ValidateOnSaveEnabled = false;

    using (var transactionScope = new TransactionScope(TransactionScopeOption.Required, new System.TimeSpan(0, 30, 0)))
    {
        context.BulkInsert(PeopleList, options => options.BatchTimeout = 0);
        context.SaveChanges();
        transactionScope.Complete();
    }
}

【问题讨论】:

  • 研究交易。请注意,回滚数百万个插入可能需要一段时间。
  • 由于您使用一个上下文实例,理论上您可以调用一次SaveChanges(并设置_people.State而不是_people.State_ID),使其成为一个要么成功要么失败的原子操作。但如果它真的是关于那么多数据,那么 EF 肯定不是正确的工具。

标签: c# .net sql-server entity-framework


【解决方案1】:

您可以使用SQLtransaction来回滚。它由 EF 支持。

using (var context = new SchoolContext())
{
    using (DbContextTransaction transaction = context.Database.BeginTransaction())
    {
        try
        {
            //**TODO: Do your bulk insert codes here**
            
            // Save changes data in context
            context.SaveChanges();
            
            // Commit changes
            transaction.Commit();
        }
        catch (Exception ex)
        {
            // Rollback all changes
            transaction.Rollback();
        }
    }
}

参考:https://learn.microsoft.com/en-us/ef/core/saving/transactions

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2016-09-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-04-07
    • 1970-01-01
    相关资源
    最近更新 更多