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