ベース リポジトリで次のコードを使用して、変更されたプロパティ名と古い DB 値のディクショナリを取得しました。新しい値は、TModel オブジェクト自体で簡単に取得できます。
private Dictionary<string, object> GetModifiedProperties(TModel model)
{
var entry = Context.Entry(model);
// entry is detached.
// set entry to database entry and its CurrentValues to model values
if (entry.State == EntityState.Detached)
{
object key = model.GetType().GetProperty("Id").GetValue(model);
if (key == null)
{
throw new InvalidOperationException("The Entity you desire to update does not contain an Id value.");
}
var dbModel = Context.Set<TModel>().Find(key);
var dbEntry = Context.Entry(dbModel);
dbEntry.CurrentValues.SetValues(model);
entry = dbEntry;
//entry.State = EntityState.Modified;
}
var modifiedProps = new Dictionary<string, object>();
foreach (var propertyName in entry.CurrentValues.PropertyNames)
{
// copy only changed values to dict
var prop = entry.Property(propertyName);
if (prop.IsModified)
{
modifiedProps.Add(propertyName, prop.OriginalValue);
}
}
return modifiedProps;
}
残念ながら、Key プロパティを取得するエレガントな方法は見つかりませんでした。しかし、「Id」はうまくいきました。変更されたプロパティのみがディクショナリに表示されます。まさにあなたが望むものではありませんが、一緒に働くものです。
編集: DAL に Unit of Work パターンを使用しています。すべてのリポジトリは、このコードの元である私のベース リポジトリから派生しています。update メソッドは GetModifiedProperties() メソッドをトリガーします。そのような更新メソッドを書くことができます:
UnitOfWork.CutomerRepository.Update(Customer updated, out Dictionary<string, object> changedProps);