首页 > 解决方案 > 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);entryentry.CurrentValues.SetValues(proje);

标签: entity-framework-core

解决方案


对于 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只将实际更改的属性标记为已修改,并且更新语句可以更苗条,甚至根本不发生。


推荐阅读