首页 > 解决方案 > 在检查实体是否存在于 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;
}

不,这不起作用,因为实体已经被跟踪。我有几个选择来处理这个问题。

  1. 更改为Context.Where(...).AsNoTracking()
  2. 在目标中显式设置更新的字段并保存。
  3. 到处乱搞实体状态并篡改跟踪器。
  4. 删除现在并添加新的。

我无法决定哪个是最佳做法。谷歌搜索给了我默认示例,这些示例不包含在同一操作中检查预先存在的状态。

标签: c#entity-frameworkasp.net-core-5.0

解决方案


只需更改target和调用SaveChanges()的属性 - 删除更新调用。我想说的是,这些天的典型用例是输入thing实际上不是 aThing而是 a ThingViewModelThingDto或者是“携带足够数据来识别和更新事物但实际上不是的对象”的主题的其他变体数据库实体”。在这种情况下,如果手动从 ThingViewModel 更新 Thing 属性的概念让您感到厌烦,您可以查看映射器(AutoMapper 可能是最知名的,但还有很多其他的)来为您进行复制,甚至设置您如果您决定将此方法转换为 Upsert,请使用新事物


推荐阅读