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

Fab*_*uez 7 mysql dbcontext asp.net-core ef-core-2.2 entity-framework-core-2.2

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

例如:

_dbContext.AddRange(entities);
_dbContext.SaveChanges();
Run Code Online (Sandbox Code Playgroud)

我添加的实体有两个主键(复合主键),当我将它们添加到 DbContext 时,这些键已经填充在实体集合中(即我自己设置键 - 没有“自动增量”或类似的东西数据库生成密钥的地方)

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

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

谢谢

Raz*_*tru 5

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

看起来您已经决定:您想放弃该操作。

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

存在一些可以执行类似操作的库:https://github.com/borisdj/EFCore.BulkExtensions(目前仅适用于 MsSQL)

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

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

    context.BulkInsertOrUpdateAsync(entitiesList);

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

    context.BulkInsertOrUpdateOrDeleteAsync(entitiesList);

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

BulkInsertOrDropAsync 
Run Code Online (Sandbox Code Playgroud)

这会做类似的事情:

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) 
Run Code Online (Sandbox Code Playgroud)

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

  • 不幸的是,该库“目前仅支持 MsSQL”*。 (2认同)