#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();
}