![](/img/trans.png)
[英]EF Core : Update column only for modified properties from disconnected entity
[英]Why EF Core generates only parent(Game) properties updating despite State=Modified?
var game = _context.Games
.AsNoTracking()
.Where(x => x.Id == 1)
.Include(x => x.PlatformTypes)
.Include(x => x.Genres)
.Include(x => x.Publisher)
.First();
game.Description = "New Description";
_context.Attach(game).State = EntityState.Modified;
_context.SaveChanges();
// CONVERTS TO
SET NOCOUNT ON;
UPDATE [Games] SET [Description] = @p0, [Discontinued] = @p1, [Key] =
@p2, [Name] = @p3, [Price] = @p4, [PublisherId] = @p5, [UnitsInStock] =
@p6
WHERE [Id] = @p7;
SELECT @@ROWCOUNT;
SaveChanges 时,EF Core 仅生成游戏的属性(不包括嵌套实体)更新查询。 尽管 Entry 中的所有嵌套实体都具有 IsModified = true,为什么它不生成嵌套实体的更新?
代码失败是因为AsNoTracking()
告诉 EF不要跟踪对象的任何更改。 这意味着 EF 不知道Description
已更改。 其余的基于错误的假设,即所有相关实体都将被标记为已Modified
game
被保存只是因为它已附加并明确标记为已修改。 _context.Attach(game)
告诉 EF 开始跟踪任意(分离的)对象game
和任何可到达的实体作为Unchanged 。 据 EF 所知,此对象可能来自 POST 调用或 JSON 文件。 从DbContext.Attach文档:
默认情况下,使用 Unchanged 状态开始跟踪给定实体和从给定实体可达的条目。
该方法仅返回game
实体的 EntityEntry
返回实体的 EntityEntry。 该条目提供对实体的更改跟踪信息和操作的访问。
Attach
文档页面明确指出Use State to set the state of only a single entity.
此时, game
实体保持不变。 然后代码告诉 EF game
被修改了。 线
_context.Attach(game).State = EntityState.Modified;
相当于:
var gameEntry=_context.Attach(game);
gameEntry.State = EntityState.Modified;
EntityEntry仅跟踪单个实体:
提供对给定实体的更改跟踪信息和操作的访问。
它的State 属性文档明确指出:
此方法仅设置此条目表示的单个实体的状态。 它不会改变从这个实体可达的其他实体的状态。
此时EF只知道它有一个Modified实体,它不知道修改了什么。 由于使用了AsNoTracking
,因此没有可比较的先前状态。 EF必须保存对象的所有属性。
但是,没有任何相关实体被修改,因此 EF 不必更新或插入它们。 即使它们在Attach
之前被修改,EF 也不会知道,因为它们都没有被标记为Modified
。 EF 只能跟踪在Attach
之后所做的修改。
要解决此问题,请删除AsNoTracking()
:
var game = _context.Games
.Where(x => x.Id == 1)
.Include(x => x.PlatformTypes)
.Include(x => x.Genres)
.Include(x => x.Publisher)
.First();
game.Description = "New Description";
_context.SaveChanges();
关于截图
屏幕截图没有显示Publisher
等相关实体的EntityEntry
,它显示了game
成员的内部更改跟踪表。 要查找Publisher
的状态,您必须使用DbContext.Entry提取其条目并检查其状态:
var publisherEntry=_context.Entry(game.Publisher);
Console.WriteLine(publisherEntry.State);
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.