web-dev-qa-db-ja.com

Entity Frameworkでの変更の追跡のしくみ

次のコードが与えられると、EF/DbContextはcustomerオブジェクトに加えられた変更をどのように知るのでしょうか。

class Program
{
    static void Main()
    {
        using(var shopContext = new ShopContext())
        {
            var customer = shopContext.Customers.Find(7);

            customer.City = "Marion";

            customer.State = "Indiana";

            shopContext.SaveChanges();
        }
    }
}

public class ShopContext : DbContext
{
    public DbSet<Customer> Customers { get; set; }
}

public class Customer
{
    public int Id { get; set; }
    public string FirstName { get; set; }
    public string LastName { get; set; }
    public string City { get; set; }
    public string State { get; set; }
}

ありがとうございました

40
Yair Nevet

コンテキストからエンティティをロードすると、追加のデータ構造が保持されます-それをエントリと呼びましょう。エントリには、元の値と現在の値の2つの値のセットが含まれています。 SaveChangesオペレーションを実行すると、EFは顧客エンティティを通過し、エンティティの実際の状態と一致するようにエントリの現在の値を更新します-このオペレーションはと呼ばれます変更。 SQLコマンドの生成中に、EFは現在の値と元の値を比較し、SQL更新ステートメントを作成して、データベース内の変更された値を変更します。この操作はスナップショット変更追跡と呼ばれ、EFはエントリにスナップショットを保持します。

エンティティのプロパティに値を割り当てると同時に、エントリの現在の値を変更する動的変更追跡と呼ばれる代替手段があります。動的変更追跡には特定の要件があります(エンティティのすべてのプロパティはvirtualである必要があるなど)。これは、実行時にクラスを動的プロキシにラップする必要があるためです。これは以前は望ましい方法でしたが、複雑なシナリオでのパフォーマンスの問題のため、スナップショットの変更の追跡が現在デフォルトで使用されることになっています。

54
Ladislav Mrnka