Я столкнулся с подобной проблемой, и AsNoTracking не был подходящим вариантом для моей ситуации, поэтому я придумал что-то, что мне подходит достаточно: сначала «клонировать» сущность, затем внести изменения.
public T Clone<T>(T entity)
where T : class, new() {
var clone = new T();
var properties = typeof(T).GetProperties(BindingFlags.Public | BindingFlags.Instance | BindingFlags.FlattenHierarchy)
.Where(a => a.CanRead &&
a.CanWrite &&
a.GetMethod.IsFinal);
foreach (var property in properties) {
property.SetValue(clone, property.GetValue(entity));
}
return clone;
}
а затем сравните клон с измененным.
public string GenerateChangeText<T>(T original, T current)
where T : class, new() {
var properties = typeof(T).GetProperties(BindingFlags.Public | BindingFlags.Instance | BindingFlags.FlattenHierarchy)
.Where(a => a.CanRead &&
a.CanWrite &&
a.GetMethod.IsFinal);
var changes = string.Empty;
foreach (var property in properties) {
var originalValue = property.GetValue(original);
var currentValue = property.GetValue(current);
if (originalValue == null && currentValue == null) continue;
if ((originalValue != null && !originalValue.Equals(currentValue)) ||
(currentValue != null && !currentValue.Equals(originalValue))) {
changes += $" changed {property} from {original ?? "NULL"} to {current ?? "NULL"}.";
}
}
return changes;
}