【发布时间】:2021-11-08 15:31:48
【问题描述】:
我正在尝试使用 .netCore 2.1 从数据库中删除超过 5000 条记录。我有以下方法可以正常工作,但是需要的时间太长。
public async Task<bool> deleteAdhocDetails(int[] id)
{
var status = false;
for (var x = 0; x < id.Length; x++)
{
var existingReward = await _context.AdhocRewardInfo
.Where(d => d.RowID == id[x])
.FirstOrDefaultAsync<AdhocRewardInfo>();
if ((existingReward != null) && (existingReward.HaloRewardCode != null))
{
try
{
//removing existingReward
_context.AdhocRewardInfo.Remove(existingReward);
await _context.SaveChangesAsync();
status = true;
}
catch (Exception e)
{
throw e;
}
}
}
return status;
}
我目前正在使用 EFCore.BulkExtensions 插入记录,它运行良好。我尝试使用 BulkDelete,但似乎没有什么不同。我也尝试使用 Z.EntityFramework.Extensions.EFCore 但也无法让它工作。我还应该提到我对此有点陌生。如果有人能指出我正确的方向,我将不胜感激。谢谢
在 adhoc.service.ts 中:
deleteAdhocRecipients(id: number[]): Promise<boolean> {
return this.http.put<boolean>(this.baseUrl + 'deleteAdhocDetails', id)
.toPromise();
}
在 .ts 文件中:
this.general
.load(this.aService.deleteAdhocCampaign(this.adhocForm.get('create.id').value))
.then(
y => {
if (deleteArr.length > 0) {
this.general.load(this.aService.deleteAdhocRecipients(deleteArr))
.then(
f => this.router.navigate(['/adhoc-campaign/lookup'])
);
} else {
this.router.navigate(['/adhoc-campaign/lookup']);
}
}
);
【问题讨论】:
-
不是这样的。 EF Core 是一个 ORM - 它将对象映射到关系表。 ORM 不适用于批处理或报告操作。在这种情况下没有对象,只有行。
using EFCore.BulkExtensions for inserting records and it works nicely.不是真的。 EF Core 没有这种能力。此类在后台所做的是将对象转换为行并使用 SqlBulkCopy 执行BULK INSERT会执行的相同操作。没有BULK DELETE,这些扩展(实际上来自同一作者)只是写出与您相同的 DELETE 语句 -
顺便说一句,这段代码存在很多问题,包括对 EF Core 的严重误用。
SaveChanges仅用于一次,用于持久化并将更改提交到数据库。您可以编写_context.AdhocRewardInfo.Where(d => ids.Contains(d.RowID)来加载所有相关实体,在循环中对它们调用Remove,并且仅在循环调用SaveChanges一次 之后。 EF Core 将生成并执行 DELETE 语句。这仍然比DELETE someTable where Id in (1,2,3,4..)慢很多,但比执行一个接着一个 DELETE 快很多 -
是否有理由需要在循环中保存?
-
这些 ID 是从哪里来的?您可以编写带有生成 ID 的条件的
DELETE ... WHERE查询,以避免使用单个 ID。如果列表来自外部文件,你可以使用 Dapper 轻松编写参数化DELETE,例如connection.Execute("DELETE from MyTable where ID in @ids",new {ids=id});。不幸的是,IN最多可以处理大约 2000 个项目。另一种选择是将所有 ID 插入临时/临时表并写入DELETE MyTable from MyTable inner join tempTable on MyTable.ID=TempTable.ID -
@PanagiotisKanavos,谢谢你的建议和建议,我会试试看的。
标签: c# .net-core entity-framework-core