假设我有一个10,000个对象的集合,我需要使用Entity Framework添加到数据库中(我认识到EF并不适合这个任务,但让我们用它来运行它现在)。出于这个问题的目的,我们将做出以下假设:
IDENTITY
。我可以通过以下两种方式之一在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()
(或反之亦然)是否有任何优势?
答案 0 :(得分:1)
所以这个问题简要讨论了"更新" vs a" insert"就数据库命令而言:
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 :(得分:1)
最好的答案是使用AddRange。然而, 通过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
(此库不是免费的)
通过允许您一次保存多个实体,此库可以提高您的代码效率。支持所有批量操作:
示例:
// 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;
});