实体框架:AddOrUpdate()与循环Add()的性能

问题描述 投票:0回答:2

让我说我有一个10,000个对象的集合,我需要使用Entity Framework添加到数据库中(我认识到EF不适合这个任务,但现在让它运行它)。出于这个问题的目的,我们将做出以下假设:

  1. 只有一个表,带有IDENTITY主键。
  2. 桌子是空的。
  3. 对象很简单 - 一切都是原始数据类型(int,bool,string等)

我可以通过以下两种方式之一在Entity Framework中执行此操作:

// Option 1
foreach (var item in largeCollection)
{
    _context.SomeTable.Add(item);
}

_context.SaveChanges();

// Option 2
_context.SomeTable.AddOrUpdate(largeCollection);
_context.SaveChanges();

一种方法的性能本质上是好于还是差于另一种?或者他们都转换成相同数量的单行INSERT陈述?

换句话说,从性能的角度来看,在将多个项目插入数据库时​​,使用Add()而不是AddOrUpdate()(或反之亦然)是否有任何优势?

c# entity-framework
2个回答
1
投票

所以这个问题简要讨论了数据库命令方面的“更新”与“插入”之间的区别:

Cost of Inserts vs Update in SQL Server

此外,根据官方MSDN文档(https://msdn.microsoft.com/en-us/library/hh846520(v=vs.103).aspx),添加或更新执行所谓的“upsert”,这基本上是一种奇特的说法,如果存在则更新行,如果不存在则插入行。

所以现在有了这些信息,Add()是更好的方法似乎是合乎逻辑的。此外,鉴于这个特定的应用程序最初用于填充数据库(如果我在这个假设上错了,请纠正我),看起来好像做一个AddOrUpdate()毫无意义,因为没有什么可以更新。


1
投票

最好的答案是使用AddRange。但是,Add的FAR方式比AddOrUpdate更高效。

AddOrUpdate

对每个实体执行数据库往返,以检查它是否已存在于目标表中。

因此,即使您的表为空,如果在10,000个对象上使用AddOrUpdate,也将执行10,000个数据库往返以检查数据是否存在。

Add方法将在更改跟踪器中添加实体,并在添加每个记录后调用DetectChanges方法。

因此,如果添加10,000个对象,则会调用DetectChanges方法10,000次,如果您有一些关系,则可能需要超过1分钟

见:Performance-Add

的AddRange

AddRange方法将添加所有实体,并在添加所有实体后调用DetectChanges方法。

因此,如果添加10,000个对象,则会调用一次DetectChanges方法。

_context.SomeTable.AddRange(largeCollection);

在所有这些情况下,一旦调用SaveChanges,将执行10,000次额外的数据库往返以保存实体,这些实体也可能非常慢。

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

(这个图书馆不是免费的)

通过允许您一次保存多个实体,该库可以提高代码的效率。支持所有批量操作:

  • BulkSaveChanges
  • BulkInsert
  • BulkUpdate
  • Bulkdelete
  • BulkMerge
  • 批量同步

例:

// 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 Primary Key
context.BulkMerge(customers, operation => {
   operation.ColumnPrimaryKeyExpression = 
        customer => customer.Code;
});
© www.soinside.com 2019 - 2024. All rights reserved.