Entity framework 使用实体框架进行批量插入/更新的有效方法

Entity framework 使用实体框架进行批量插入/更新的有效方法,entity-framework,Entity Framework,我有一个实体列表,我想将它们插入数据库。如果实体已按原样存在于数据库中,则需要跳过该实体。如果它在数据库中,但具有不同的值,则需要更新它 除了对每个项目进行db调用之外,还有其他方法可以做到这一点吗 我的计划是尝试插入,如果在键上引发了唯一约束异常,则执行更新。EF不适合批量插入。 对于1000条记录来说,它还可以,但是大的数字100k加上它的速度慢 如果您计划使用EF 尝试AddOrUpdate方法,而不是插入/更新 禁用跟踪, 每1000条或更少记录提交一次。 乙二醇 如果复制不相关的数据,

我有一个实体列表,我想将它们插入数据库。如果实体已按原样存在于数据库中,则需要跳过该实体。如果它在数据库中,但具有不同的值,则需要更新它

除了对每个项目进行db调用之外,还有其他方法可以做到这一点吗


我的计划是尝试插入,如果在键上引发了唯一约束异常,则执行更新。

EF不适合批量插入。 对于1000条记录来说,它还可以,但是大的数字100k加上它的速度慢

如果您计划使用EF

尝试AddOrUpdate方法,而不是插入/更新 禁用跟踪, 每1000条或更少记录提交一次。 乙二醇

如果复制不相关的数据,您可以并行地尝试这些表,但在这种情况下不要使用实体框架。只要使用一个存储过程,根据EF使用的版本/方法,您可能需要扩展DbContext或从实体模型添加映射


如果您使用的是SQL Server,那么在存储过程中,一定要使用能够高效完成所需任务的命令:如果不存在,则插入;如果存在,则更新。在一个高效的SQL查询中完成所有操作。

我已经对此进行了扩展

而且使用起来非常简单

using(var context = new MyDbContext())
{
    context.BulkInsert(hugeCollectionOfEntities);
}
创建临时表: SqlCommandstring.Format从{1}将顶部0*选择到{0}

大容量插入数据到it中-需要调整上面提到的扩展实体框架以支持临时表名称,但在其他方面是正确的-或者滚动一些代码并使用SqlBulkCopy

构造一个MERGE语句


如果你挖掘一个属性列表,你可以使2和3通用。我可以在大约20秒内读取并合并150000行。

如果在批处理的中间有一个唯一的约束异常,我认为这将是很尴尬的。如果您可能有很多独特的约束违反,批量提交实际上就没那么有用了。实际上,关于保存数据包的评论是建议您将它们保持在较小的位置,最大1000个,不要太大。Ef不能很好地应付饱肚子。如果吞吐量正常,则使用单记录提交。您还可以尝试使用较小的数据包,例如10,如果失败,请为失败的数据包重试单个REC。我只是尝试各种方法来获得更好的吞吐量。如果使用SqlBulkCopy,它不可能全部出现在一个查询中。它需要一个SP来创建临时表,然后需要一个SP来与中间的.NET文件进行合并。sqlmerge命令完成了所有需要的操作。例如,您可以通过将实体作为参数表值参数传递来调用存储过程,Merge将完成所有工作。我让它工作了,但现在他们说它需要在SQL Server 2000上运行。有什么想法吗?我讨厌这就是答案。现在你已经把你的代码紧密地耦合到一个特定的数据库实现上了。这里的可能副本是一个很好的答案。[ [1]:Telerik DataAccess可以进行批量更新只是提醒一下:此库不支持导航属性。如果您具有父子表关联,则在插入后,您的子表元素的外键将设置为0。这不处理更新方面的问题。它是免费的吗?还是我需要付费?与此相同吗?@Al如果你愿意的话,你可以付给我:D,但它是免费开放的-source@maxlego非常感谢。
using(var context = new MyDbContext())
{
    context.BulkInsert(hugeCollectionOfEntities);
}