Поскольку довольно сложно получить ответ на вопросы EFCore, вот решение, которое я придумала.
Ознакомьтесь с разделом State.Modified . Я перебираю каждую сущность, а затем перебираю каждое свойство. В этом случае я использую текущие и исходные значения для сравнения и добавляю их в свою таблицу аудита только тогда, когда что-то изменилось.
На конце метода я удаляю сущности, которые не изменились, из моей таблицы аудита. Простая мимле
Вы можете использовать это var databaseValues = entry.GetDatabaseValues();
To для ваших пользовательских отключенных сценариев.
var auditEntries = new List<AuditEntry>();
foreach (var entry in ChangeTracker.Entries())
{
if (entry.Entity is Audit || entry.State == EntityState.Detached || entry.State == EntityState.Unchanged)
continue;
var auditEntry = new AuditEntry(entry) {TableName = entry.Metadata.Relational().TableName};
auditEntries.Add(auditEntry);
var databaseValues = entry.GetDatabaseValues();
foreach (var property in entry.Properties)
{
if (property.IsTemporary)
{
// value will be generated by the database, get the value after saving
auditEntry.TemporaryProperties.Add(property);
continue;
}
string propertyName = property.Metadata.Name;
if (property.Metadata.IsPrimaryKey())
{
auditEntry.KeyValues[propertyName] = property.CurrentValue;
continue;
}
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.CurrentValue != null)
{
if (databaseValues[propertyName] != null && property.CurrentValue != null)
{
if (property.IsModified && !property.CurrentValue.Equals(databaseValues[propertyName]))
{
auditEntry.OldValues[propertyName] = databaseValues[propertyName];
auditEntry.NewValues[propertyName] = property.CurrentValue;
}
}
}
break;
}
}
if (auditEntry.NewValues.Equals(auditEntry.OldValues) || auditEntry.NewValues.Count == 0 && auditEntry.OldValues.Count == 0)
{
auditEntries.Remove(auditEntry);
}