entity-framework-core - EntityEntry.OriginalValues.ToObject() 与 EntityEntry.Entity 相同
问题描述
我只是尝试使用下面的ProjeleriGuncelle方法更新实体。
当我尝试使用EntityEntry.OriginalValues.ToObject()在覆盖的SaveChangesAsync中访问对象的原始值时,我看到该对象包含当前值而不是旧值。
我错过了什么吗?我希望clonedTypedEntity在更新之前具有这些值。
public async Task<ActionResult<int>> ProjeleriGuncelle(Proje proje)
{
var projeFound = DataContext.Projeler.AsNoTracking().FirstOrDefault(p => p.EntegrasyonId == proje.EntegrasyonId);
var entry = DataContext.Entry<Proje>(projeFound);
//Database entry is updated with the proje object as expected
entry.CurrentValues.SetValues(proje);
entry.State = EntityState.Modified;
await DataContext.SaveChangesAsync();
}
public override Task<int> SaveChangesAsync(CancellationToken cancellationToken = new CancellationToken())
{
ChangeTracker.DetectChanges();
var modifiedEntries = this.ChangeTracker.Entries();
foreach (var modifiedEntry in modifiedEntries)
{
//modifiedEntry.OriginalValues.ToObject() returns the object with the currrent values instead of the original values before update
if (modifiedEntry.OriginalValues.ToObject() is not IVersionable clonedTypedEntity) continue;
clonedTypedEntity.Id = 0;
clonedTypedEntity.UstSurumId = (modifiedEntry.Entity as IVersionable)?.Id;
Add(clonedTypedEntity);
}
return base.SaveChangesAsync(cancellationToken);
}
更新 :
当我在查询projeFound时删除AsNoTracking()时,确实会在更新之前返回值。但我不明白这种行为,因为有了声明,我希望该对象被跟踪,并且通过更新它,我希望能够访问原始值。modifiedEntry.OriginalValues.ToObject()
var entry = DataContext.Entry<Proje>(projeFound);
entry
entry.CurrentValues.SetValues(proje);
解决方案
对于 EF,原始值是它开始跟踪时的值,也就是entry.State = EntityState.Modified;
被调用的时间。EF 没有注意到前一行代码中发生的更改。
您可以通过交换两行来解决它:
entry.State = EntityState.Modified; // attaches and stores original values
entry.CurrentValues.SetValues(proje);
一个改进是附加条目并让更改跟踪器确定实体是否真的被修改。
entry.State = EntityState.Unchanged; // attaches and stores original values
entry.CurrentValues.SetValues(proje);
现在SetValues
只将实际更改的属性标记为已修改,并且更新语句可以更苗条,甚至根本不发生。
推荐阅读
- leaflet - 搜索特定名称 onEachFeature
- python - for 循环中的 if 语句打印两次
- html - 使用 Universal SSR 使用 angular2+ 指令播放视频 html
- sql - SQL 表底部的 NULL 值 - SQL Server 2000
- java - 转换地图的最佳方法
- tfs - 发布分支可以用于暂存吗?
- c# - 如何在控制器之外获取 Request.Scheme 属性。.(净核 2.2)
- geotiff - 无法使用光栅获得单波段 tiff 图像的彩色图
- ssas - 具有行安全过滤器和对象级安全过滤器的两个角色的用户
- java - ArrayList null 不为空