【问题标题】:EF Core : Update column only for modified properties from disconnected entityEF Core:仅更新来自断开实体的修改属性的列
【发布时间】:2021-02-05 11:55:32
【问题描述】:

我正在使用带有 SQL Server 的 Entity Framework Core 3.1。

我搜索如何更新列仅用于断开实体的修改属性,例如:

public void UpdateOrderCustomer(int orderId, string customerName)
{
    var order = new Order { Id = orderId };

    using(var context = new MyDbContext())
    {
        context.Update(order);
        order.Customer = customerName;
        context.SaveChanges();
    }
}

但这会更新所有订单的列。

一种解决方案是在更新属性之前加载实体,例如:

public void UpdateOrderCustomer(int orderId, string customerName)
{
    using(var context = new MyDbContext())
    {
        var order = context.Orders.Single(o => o.Id == orderId);
        order.Customer = customerName;
        context.SaveChanges();
    }
}

但是要加载实体,这会执行一个额外的无用查询。

我希望有一个BeginTracking 方法,但我没有找到这个或任何类似的功能。

如何仅为来自断开连接的实体的已修改属性更新列?

【问题讨论】:

  • 我认为您要求的是根本不可能的事情。考虑一下:您在某个时间点从数据库中加载给定实体,然后将其发送到远程客户端。在客户端发回断开连接的实体之前可能已经过了相当长的一段时间 - EF 不可能“等待”这么长时间来跟踪信息 - 所以它不知道当你前一段时间加载它。它到底应该如何弄清楚发生了什么变化?现在重新加载并比较是唯一可行的方法......
  • 我理解并且在大多数情况下我都会这样做。但有时您只想更新 1 列而不关心行的状态。我同意,这是一个微优化问题。
  • 不确定这是否可行,但您可以附加实体并将要更新的列标记为已修改。 context.Attach(customer);context.Entry(customer).Property("FirstName").IsModified = true;

标签: c# .net entity-framework .net-core entity-framework-core


【解决方案1】:

您可以像这样更新单个属性或分离的实体:

public void ChangePassword(int userId, string password)
{
  var user = new User() { Id = userId, Password = password };
  using (var db = new MyEfContextName())
  {
    db.Users.Attach(user);
    db.Entry(user).Property(x => x.Password).IsModified = true;
    db.SaveChanges();
  }
}

【讨论】:

  • 这项工作,但我更喜欢使用跟踪器的解决方案。如果没有发布更好的解决方案,我会接受这个答案。
  • @Vernou,我不知道。这样做的主要好处是您不需要先将实体从数据库加载到内存中
猜你喜欢
  • 2021-11-06
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2022-10-18
  • 2014-12-03
  • 2018-04-03
  • 2020-09-04
相关资源
最近更新 更多