【问题标题】:How to Update Existing Disconnected Entity如何更新现有的断开连接的实体
【发布时间】:2020-10-02 20:01:22
【问题描述】:

我有这段代码在 EntityFrameworkCore 中工作。

public void SaveProject(Project item)
    {
        var existing = _context.Projects.FirstOrDefault(a => a.Id == item.Id);
        existing.Description = item.Description;
        existing.IsArchived = item.IsArchived;
        existing.IsDeleted = item.IsDeleted;
        existing.Name = item.Name;
        _context.SaveChanges();

    }

它获取一个断开连接的实体,在数据库中找到它,然后应用更改。

有没有更好的方法来做到这一点?

我不想调用数据库。换句话说,我希望能够将实体标记为已修改,然后调用 SaveChanges()。

有没有办法做到这一点?

【问题讨论】:

    标签: entity-framework-core


    【解决方案1】:

    如果您确定该项目存在于数据库中,您可以使用 DbContext 的 Attach 方法如下

    public void SaveProject(Project item)
    {
        _context.Projects.Attach(item);
        _context.Entity(item).State=EntityState.Modified;
        _context.SaveChanges();
    }
    

    【讨论】:

    • 我认为这将更新实体的所有属性
    【解决方案2】:

    在 EntityFramework Core 中,现在可以使用 Update 方法来完成:

     DbContext.Update<Item>(item);
     this.SaveChanges();
    

    在 2.1 版中,如果 Id 属性是自动生成的,则 Update 方法现在可用于新实体和现有实体。

    The Docs

    这样做的缺点是 所有 属性都被标记为已修改,即使它们是相同的。这样做的问题是,如果您在数据库触发器中记录更改,那么每个属性都将被标记为已更改,即使它们没有更改。如果您只想更新特定属性,则需要从数据库中获取实体,根据需要进行更新,然后保存。

    【讨论】:

      【解决方案3】:

      在通过主键找到断开连接的实体后,我创建了以下扩展方法来仅更新特定值(在updateAction 中指定)。

      场景:我有一个 ASP Core 页面,它在其视图中仅使用实体的一部分,并且通过不具有所有字段的 DTO 从/到 Web 层传输

      public static T FindByPrimaryKey<T>(this DbContext context, T disconnectedEntity) where T : class
      {
          var keyValues = context.Model.FindEntityType(typeof(T)).FindPrimaryKey().Properties
              .Select(p => typeof(T).GetProperty(p.Name))
              .Select(p => p.GetValue(disconnectedEntity)).ToArray();
      
          var connectedEntity = context.Find<T>(keyValues);
      
          return connectedEntity;
      }
      
      public static void UpdateByPrimaryKey<T>(this DbContext context, T disconnectedEntity, Action<T> updateAction) where T : class
      {
          var connectedEntity = context.FindByPrimaryKey(disconnectedEntity);
      
          updateAction(connectedEntity);
      }
      

      【讨论】:

        猜你喜欢
        • 2018-05-12
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2010-09-07
        • 2013-10-28
        相关资源
        最近更新 更多