我有一个ASP .Net Core 2.2 Web API。在我的一个控制器操作中,我正在向MySQL数据库表添加一堆行(我正在使用Pomelo)。
例如:
_dbContext.AddRange(entities);
_dbContext.SaveChanges();
我要添加的实体具有两个主键(复合主键),并且当我将它们添加到DbContext时,这些键已经填充在实体集合中(即,我自己设置键-没有“自动增量”或类似的在数据库生成密钥的地方进行的操作
如果我要添加的任何实体已经存在于数据库中(就主键重复而言),那么显然SaveChanges()会引发异常,并且整个事务都会回滚。
是否可以告诉EF Core忽略失败的实体?即忽略数据库中已经存在的实体,并提交成功的实体(即数据库中不存在的实体)?代替当前的行为是抛出异常并回滚整个事务?
谢谢
答案 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,但是它将保留您的数据不变。