在 EF Core 中忽略重复条目并在 DbContext.SaveChanges() 上提交成功的条目

Ignore duplicate entries and commit successful ones on DbContext.SaveChanges() in EF Core

我有一个 ASP .Net Core 2.2 Web API。在我的一个控制器操作中,我将一堆行添加到 MySQL 数据库 table(我正在使用 Pomelo)。

例如:

_dbContext.AddRange(entities);
_dbContext.SaveChanges();

我要添加的实体有两个主键(复合主键),当我将它们添加到 DbContext 时,这些键已经填充到实体集合中(即我自己设置键 - 没有 "auto increment" 或数据库生成密钥的任何类似内容)

如果我添加的任何实体已经存在于数据库中,就重复的主键而言,显然 SaveChanges() 会抛出异常,整个事务将回滚。

有没有办法告诉 EF Core 忽略失败的实体?即忽略数据库中已经存在的实体,并提交成功的实体(即数据库中不存在的实体)?而不是抛出异常并回滚整个事务的当前行为?

谢谢

看来您遇到了业务问题。首先,您需要确定当您已经拥有一个具有相同 ID 的实体并且有人试图插入一个具有相同 ID 的新实体(新信息)时会发生什么。

看来你已经决定了:你想放弃这个动作。

这有点不寻常,因为如果您从 API 的客户端收到一些关于数据库中已经存在的实体的新数据 -> 看起来更像是更新。

有一些库可以做类似的事情:https://github.com/borisdj/EFCore.BulkExtensions(目前仅适用于 MsSQL)

使用此库(这是一个已知的库,Microsoft 已将其称为 EF Core 工具:https://docs.microsoft.com/en-us/ef/core/extensions/)您可以:

  • 如果找到具有相同 ID 的实体 (Upsert),则插入或更新所有数据(所有列):

    context.BulkInsertOrUpdateAsync(entitiesList);

  • 将数据库中的实体与您从客户端收到的任何实体同步:

    context.BulkInsertOrUpdateOrDeleteAsync(entitiesList);

很可能您找不到已经为您的案例实现的东西,但您可以通过以下方式调整此库:

BulkInsertOrDropAsync 

这会做类似的事情:

WHEN MATCHED THEN UPDATE SET A.ID=A.ID --The ID's are already the same so nothing will happen
WHEN NOT MATCHED THEN INSERT(A.ID,A.NAME,A.CODE,A.DESCRIPTION) 

这并不是真正的 DROP,但它会让您的数据完好无损。