我有一个实体列表,我想将它们插入数据库。如果实体已按原样存在于数据库中,则需要跳过它。如果它在数据库中但具有不同的值,则需要对其进行更新。
除了对每个项目进行 db 调用之外,还有什么方法可以做到这一点?
我的计划是尝试插入,如果键上的唯一约束异常被抛出然后进行更新。
我有一个实体列表,我想将它们插入数据库。如果实体已按原样存在于数据库中,则需要跳过它。如果它在数据库中但具有不同的值,则需要对其进行更新。
除了对每个项目进行 db 调用之外,还有什么方法可以做到这一点?
我的计划是尝试插入,如果键上的唯一约束异常被抛出然后进行更新。
在这种情况下不要使用实体框架。只需使用存储过程(如何取决于您与 EF 一起使用的版本/方法,您可能必须扩展您的DbContext
或从实体模型添加映射)。
如果您使用的是 SQL Server,那么在您的存储过程中,请使用MERGE
能够有效执行您需要的命令:如果不存在则插入,如果存在则更新。一切尽在一个高效的 SQL 查询中。
EF 不适合 BULK 刀片。对于 1000 条记录来说还可以,但大量记录(超过 10 万条)速度很慢。
如果您打算使用 EF。
例如
Context.Set<TPoco>().AddOrUpdate(poco);
//...
Context.Configuration.AutoDetectChangesEnabled =
//..
Context.SaveChanges();
如果复制不相关的数据,您可以并行尝试这些表(doh)
我已经为该 https://efbulkinsert.codeplex.com/进行了扩展
而且使用起来非常简单
using(var context = new MyDbContext())
{
context.BulkInsert(hugeCollectionOfEntities);
}
创建一个临时表: SqlCommand(string.Format("SELECT TOP 0 * INTO {0} FROM {1}...
向其中批量插入数据——上面提到的 Entity Framework Extended 需要调整以支持临时表名称,但否则处于正确的轨道上——或者滚动一些代码并使用 SqlBulkCopy。
构造一个 MERGE 语句。
如果您挖掘一个属性列表,您可以使 (2) 和 (3) 通用。我可以在大约 20 秒内读取和合并 150,000 行。