c# - 在检查实体是否存在于 EF Core 时适当更新实体
问题描述
我有以下方法更新实体。我唯一的区别是,当提供一个不存在的 ID 时,我得到了一个严厉的例外。
public bool Update(Thing thing)
{
Context.Things.Update(thing);
int result = Context.SaveChanges();
return result == 1;
}
所以我添加了一个检查来控制抛出的异常(加上一些不错的日志记录和其他便利)。最终,我打算完全跳过呕吐。
public bool UpdateWithCheck(Thing thing)
{
Thing target = Context.Things.SingleOrDefault(a => a.Id == thing.Id);
if (target == null)
throw new CustomException($"No thing with ID {thing.Id}.");
Context.Things.Update(thing);
int result = Context.SaveChanges();
return result == 1;
}
不,这不起作用,因为实体已经被跟踪。我有几个选择来处理这个问题。
- 更改为
Context.Where(...).AsNoTracking()
。 - 在目标中显式设置更新的字段并保存。
- 到处乱搞实体状态并篡改跟踪器。
- 删除现在并添加新的。
我无法决定哪个是最佳做法。谷歌搜索给了我默认示例,这些示例不包含在同一操作中检查预先存在的状态。
解决方案
只需更改target
和调用SaveChanges()
的属性 - 删除更新调用。我想说的是,这些天的典型用例是输入thing
实际上不是 aThing
而是 a ThingViewModel
,ThingDto
或者是“携带足够数据来识别和更新事物但实际上不是的对象”的主题的其他变体数据库实体”。在这种情况下,如果手动从 ThingViewModel 更新 Thing 属性的概念让您感到厌烦,您可以查看映射器(AutoMapper 可能是最知名的,但还有很多其他的)来为您进行复制,甚至设置您如果您决定将此方法转换为 Upsert,请使用新事物
推荐阅读
- bash - 如果外部文件中存在值,则将数据添加到 CSV 中的行
- flutter - 如何从 ThemeData 设置过度滚动
- c - 在一行中获得多个输入 C
- rust - 如何在排序列中插入 max(ordering) + 1 的表?
- javascript - 展开矩阵数组 - 类型错误:无法读取未定义的属性“反向”
- angular - 角度路由始终返回默认页面
- amazon-web-services - AmazonMQ 仅限 5 个消费者
- typescript - 在打字稿中,我不明白为什么会收到错误“Service1 | 服务2 | null' 不可分配给类型 '(Service1 & Service2) | 无效的'
- ruby-on-rails - Rails 6 表单不显示错误 - nil:NilClass 的未定义方法“错误”
- python - Pandas 根据另一列的条件重置 cumsum()