EF Core:更新实体而不先查询它

mco*_*ont 4 entity-framework-core

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

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

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

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

order.Name = "smth";

db.SaveChanges();
Run Code Online (Sandbox Code Playgroud)

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

UPDATE "Orders" SET "Name" = @p0
WHERE "Id" = @p1;
Run Code Online (Sandbox Code Playgroud)

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

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

谢谢。

Oli*_*bes 5

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();
Run Code Online (Sandbox Code Playgroud)

  • 啊,对了!我没有想到这一点。我想解决方法是强制将该值视为已修改:`db.Entry(order).Property(x => x.Amount).IsModified = true;`。虽然有点冗长。 (2认同)