Получить исходное значение отдельного объекта

#c# #asp.net-core #entity-framework-core

#c# #asp.net-core #сущность-фреймворк-ядро

Вопрос:

У меня есть API, созданный с использованием ASP.NET CORE. после того, как он передаст данные клиентским приложениям (веб-приложениям JS), вот так:

 public IEnumerable<Article> GetAvaliableArticles()
{
    ThrowIfDisposed();
    return Entities.Where(s => s.IsAvailable).OrderBy(x => x.DisplayOrder);
}
  

Когда клиентское приложение хочет обновить каждую статью, я прикрепляю объект обратно к контексту:

 Context.Attach(entity);
if(entity.GetType().GetProperty("ConcurrencyStamp") != null) 
{
    var propertyInfo = entity.GetType().GetProperty("ConcurrencyStamp");
    propertyInfo.SetValue(entity, Guid.NewGuid().ToString());
}
Context.Update(entity);
await Context.SaveChangesAsync(cancellationToken);
  

Однако, когда я пытаюсь проверить изменение в EF, оно не получает предыдущее значение Article. Исходное и новое значения одинаковы.

 switch (entry.State) 
{
    case EntityState.Added:
        auditEntry.NewValues[propertyName] = property.CurrentValue;
        break;
    case EntityState.Deleted:
        auditEntry.OldValues[propertyName] = property.OriginalValue;
        break;
    case EntityState.Modified:
        if (property.IsModified) 
        {
            auditEntry.OldValues[propertyName] = property.OriginalValue;
            auditEntry.NewValues[propertyName] = property.CurrentValue;
        }
        break;
}
  

Я хочу property.OriginalValue быть предыдущим значением перед обновлением.

Ответ №1:

Для Context.Attach(entity); значения по умолчанию или исходного значения поступают из entity , которое вы передали со стороны клиента, вместо запроса к базе данных.

В качестве обходного пути вы могли бы попытаться entry.GetDatabaseValues().GetValue<object>(property.Metadata.Name) получить исходное значение базы данных.

 public override int SaveChanges()
{
    ChangeTracker.DetectChanges();
    var entries = ChangeTracker.Entries().Where(e => !(e.Entity is Audit) amp;amp; e.State != EntityState.Detached amp;amp; e.State != EntityState.Unchanged);
    foreach (var entry in entries)
    {
        switch (entry.State)
        {                    
            case EntityState.Modified:
                foreach (var property in entry.Properties)
                {
                    if (property.IsModified)
                    {
                        var original = entry.GetDatabaseValues().GetValue<object>(property.Metadata.Name);
                        var current = property.CurrentValue;
                    }
                }
                break;
        }
    }
    return base.SaveChanges();
}