EF Core:修改TransferedAt但不触发ModifiedAt更新的实现问题
解决方案
你的核心问题是:既要将TransferedAt的修改保存到数据库,又要避免ModifiedAt被自动更新——当前只要实体处于Modified状态,SaveChanges时的逻辑就会覆盖ModifiedAt。以下是两种可行的解决方法:
方法一:调整SaveChanges中的修改逻辑(推荐)
在你重写的SaveChanges逻辑里增加判断:只有当实体存在除TransferedAt外的其他修改属性时,才更新ModifiedAt。这样单独修改TransferedAt时,不会触发ModifiedAt的更新。
修改后的ChangeTracker处理代码:
var now = DateTime.UtcNow; foreach (var ent in this.ChangeTracker.Entries() .Where(p => p.State == EntityState.Added || p.State == EntityState.Modified || p.State == EntityState.Deleted)) { if (ent.State == EntityState.Added) { ((ICreated)ent.Entity).CreatedAt = now; } else if (ent.State == EntityState.Modified ) { // 获取所有被标记为修改的属性名 var modifiedProps = ent.Properties .Where(p => p.IsModified) .Select(p => p.Metadata.Name); // 只有当修改的属性不只是TransferedAt时,才更新ModifiedAt if (!modifiedProps.SequenceEqual(new[] { nameof(YourEntityType.TransferedAt) })) { ((IModified)ent.Entity).ModifiedAt = now; } } else if (ent.State == EntityState.Deleted) { ((IDeleted)ent.Entity).DeletedAt = now; ent.State = EntityState.Modified; //Soft delete } }
注意:把YourEntityType替换为你的实体类类型,或者直接写字符串"TransferedAt"。
之后修改TransferedAt的代码保持正常写法即可:
document.TransferedAt = now; await _context.SaveChangesAsync();
方法二:直接执行SQL更新(绕过ChangeTracker)
如果不想修改SaveChanges的全局逻辑,可以直接用SQL语句更新TransferedAt,这样ChangeTracker不会检测到实体变化,自然不会触发ModifiedAt的更新。
示例代码:
// 执行SQL更新数据库 await _context.Database.ExecuteSqlInterpolatedAsync( $"UPDATE Documents SET TransferedAt = {now} WHERE Id = {document.Id}" ); // 同步内存中实体的属性值(可选) document.TransferedAt = now;
注意:把Documents替换为你的实体对应的数据库表名。
内容的提问来源于stack exchange,提问作者Jaczura Zoltán
相关产品推荐
相关产品推荐

