【问题标题】:Quick way to update many rows更新多行的快速方法
【发布时间】:2015-12-16 00:54:23
【问题描述】:

我正在开发一个系统,该系统在工作时将使用新 ID 更新 DB 中给定数量的行。

目前我有大约 900 万行,在选择了该数据的一小部分(大约 10k 项)后,我想遍历每个项并使用新 ID 更新一列。

我目前所拥有的确实有效,但速度太慢而无法使用,因此我需要以某种方式对其进行改进。这是代码,这最初是一个 ForEach 循环,但我读到数组上的“For”循环更快,所以我尝试了这一点,但没有太大改进。

public string UpdateWithNewWidgetId(List<string> allTheWidgetIds, int newWidgetId)
    {
  var repoPerson = _repositoryFactory.CreateRepository<Person>();

        try
        {
            var person = repoPerson.GetAll(x => fieldToUpdate.Any(val => x.WidgetId == val)).ToArray;


            for (int i = 0; i < person.Length; i++)
            {
                person[i].WidgetId= newWidgetId;
                repoPerson.Update(person[i]);
            }

            repoPerson.SaveChanges();
        }
        catch (Exception ex)
        {
            //log error
        }

因此,repoPerson 会很快返回大约 10K 项的列表,但 foreach 循环需要很长时间,然后 SaveChanges(这只是执行 Context.SaveChanges())需要更长的时间。

最初我在 foreach 中有 SaveChanges,并认为这是我的问题,但从循环中删除它并没有改善问题。

【问题讨论】:

  • 我会为大型操作调用存储过程
  • 我将使用 sproc 进行调查,在上面的示例中,您建议通过 sproc 完成整个事情还是只更新?

标签: c# linq-to-entities repository-pattern


【解决方案1】:

大数据量需要看这个话题:

Bulk Update in C#

通常如果您需要执行大量插入/更新数据,Entity Framework 是不够的 - 需要使用 SqlBulkCopy 方法,它要快得多。

【讨论】:

  • SqlBulkCopy 不执行更新
  • 在我提到的主题中,使用中间表有一个很好的解决方法。
  • @MagisterCrazy 只是为了澄清一下 - 在那个链接的主题中,它是您推荐作为解决方案的选定答案还是进一步的不同答案?
  • 我认为选择的答案已经足够好了)我们之前在我们的项目中做过类似的事情。
  • 使用临时表是要走的路。
【解决方案2】:

尝试添加事务,应该加快上下文 SaveChanges 事件

using (Context context = new Context())
        {
            using (var dbContextTransaction = context.Database.BeginTransaction())
            {
             ...yours code
             context.SaveChanges();
             dbContextTransaction.Commit();
            }
        }

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2013-09-30
    • 1970-01-01
    • 2016-03-01
    • 2018-07-08
    • 1970-01-01
    • 2013-06-09
    • 1970-01-01
    • 2017-07-01
    相关资源
    最近更新 更多