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

时间:2019-05-27 10:22:01

标签: mysql asp.net-core dbcontext ef-core-2.2 entity-framework-core-2.2

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

例如:

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

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

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

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

谢谢

1 个答案:

答案 0 :(得分:1)

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

您似乎已经决定:要删除该动作。

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

有些库可以执行类似的操作:https://github.com/borisdj/EFCore.BulkExtensions(目前仅与MsSQL一起使用)

使用该库(这是一个已知的库,Microsoft已经将其称为EF核心工具: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,但是它将保留您的数据不变。