首页 > 解决方案 > EF Core:更新实体而不先查询它

问题描述

我正在寻找一种通过知道其主键来更新实体属性的方法,而无需先查询它。

我想出的解决方案是这个:

var order = new OrderEntity()
{
    Id = 5
};

db.Orders.Attach(order).State = EntityState.Unchanged;

order.Name = "smth";

db.SaveChanges();

这似乎工作正常,因为生成的 SQL 正是我所期望的:

UPDATE "Orders" SET "Name" = @p0
WHERE "Id" = @p1;

问题:这是正确的做法吗?

我在官方文档中或实际上在网络上的任何其他地方都找不到任何关于此的确认。类似的问题是关于实体框架(非核心),他们似乎使用不同的策略,比如设置EntityState.Modified而不是Unchanged. 我也尝试过,但它具有更新所有属性的效果,这不是我想要实现的。所以我想知道上面的解决方案是否缺少一些东西。

谢谢。

标签: entity-framework-core

解决方案


DbContext.Attach 方法的文档说:

默认情况下,使用未更改状态开始跟踪给定实体和可从给定实体访问的条目,但请参阅下文了解将使用不同状态的情况。
[...]
对于具有生成键的实体类型,如果实体设置了其主键值,那么它将在未更改状态下被跟踪。如果未设置主键值,则将在已添加状态下对其进行跟踪。
[...]
对于没有生成键的实体类型,状态集始终为Unchanged
[...]

因此,Unchanged甚至没有必要将状态设置为。

不过要小心。如果您设置例如order.Amount = 0m;清除金额,这将不起作用,因为不会检测到任何更改。写

var order = new OrderEntity()
{
    Id = 5,
    Amount = 1.00m; // Dummy value unequal 0.00m
};
db.Orders.Attach(order);

// Make the change    
order.Amount = 0.00m; // Now, this change will be detected.

db.SaveChanges();

推荐阅读