0

エンティティフレームワークで、エンティティフレームワークがデータベースで行う実際の変更/差分を把握することは可能ですか?

例を考えてみましょう。いくつかの行がデータベースに既に存在し、それらを再度追加しようとしているとします。行はすでに存在するため、データベースで行われた実際の変更/差分は null です。同様に、10 行を取得しようとすると、そのうち 3 行だけが更新され、その 3 行だけが必要になります。

私はDbContext.ChangeTracker同じことを達成しようとしていましたが、データベースに既に存在するかどうかに関係なく、追加/更新/削除しようとしているすべての行を返すようです。誰かがこの動作も確認できますか?

4

1 に答える 1

0

ベース リポジトリで次のコードを使用して、変更されたプロパティ名と古い 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);
于 2013-09-14T17:12:23.447 に答える