我正在使用该库来批量执行批量删除,如下所示:
while (castedEndedItems.Any())
{
var subList = castedEndedItems.Take(4000).ToList();
DBRetry.Do(() => EFBatchOperation.For(ctx, ctx.SearchedUserItems).Where(r => subList.Any(a => a == r.ItemID)).Delete(), TimeSpan.FromSeconds(2));
castedEndedItems.RemoveRange(0, subList.Count);
Console.WriteLine("Completed a batch of ended items");
}
您可以看到,我一次要删除4000批商品,并将它们作为参数传递给查询...
我正在使用此库执行批量删除:
https://github.com/MikaelEliasson/EntityFramework.Utilities
但是这样的性能是绝对糟糕的...我测试了几次应用程序并删除了80000条记录,例如,这实际上需要40分钟!?
我应该注意,我要用来删除(ItemID)的参数属于varchar(400)类型,并且出于性能原因而对其进行了索引。...
是否还有其他我可以使用或调整此查询的库以使其运行更快,因为当前的性能绝对糟糕。.::
答案 0 :(得分:4)
如果准备使用存储过程,则可以在没有任何外部库的情况下执行此操作:
@ids
创建存储过程id
列)定义SQL类型在存储过程中使用
delete from table where id in (select id from @ids);
在您的应用程序中创建一个DataTable
并填充以匹配SQL表
This answer说明了该过程。
任何其他选择都需要做到这一点–或效率较低。
答案 1 :(得分:2)
这里的任何EF解决方案都可能执行很多谨慎操作。相反,我建议手动在循环中构建SQL,例如:
using(var cmd = db.CreateCommand())
{
int index = 0;
var sql = new StringBuilder("delete from [SomeTable] where [SomeId] in (");
foreach(var item in items)
{
if (index != 0) sql.Append(',');
var name = "@id_" + index++;
sql.Append(name);
cmd.Parameters.AddWithValue(name, item.SomeId);
}
cmd.CommandText = sql.Append(");").ToString();
cmd.ExecuteNonQuery();
}
但是,由于命令上允许的参数数量有上限,因此您可能需要分批循环 this 。
答案 2 :(得分:2)
如果您不介意额外的依赖关系,则可以使用NuGet包Z.EntityFramework.Plus。
代码大致如下:
using Z.EntityFramework.Plus;
[...]
using (yourDbContext context = new yourDbContext())
{
yourDbContext.yourDbSet.Where( yourWhereExpression ).Delete();
}
简单高效。 documentation包含有关效果的确切数字。
关于许可:据我所知,版本1.8具有MIT许可:https://github.com/zzzprojects/EntityFramework-Plus/blob/master/LICENSE 较新的版本不能免费使用。