エンティティのいくつかのプロパティのみを変更できる場合、このコードではシナリオがあります。それを保証するために、我々はこのようなコードがあります。新しいインスタンスを返すようにEntity Frameworkを強制する
public void SaveCustomer(Customer customer)
{
var originalCustomer = dbContext.GetCustomerById(customer.Id);
if (customer.Name != originalCustomer.Name)
{
throw new Exception("Customer name may not be changed.");
}
originalCustomer.Address = customer.Address;
originalCustomer.City = customer.City;
dbContext.SaveChanges();
}
をこのコードの問題はdbContext.GetCustomerById
への呼び出しは、常に私にCustomer
クラスの新しいインスタンスを与えないということです。顧客が既にデータベースからフェッチされている場合、Entity Frameworkはインスタンスをメモリに保持し、後続のすべての呼び出しでインスタンスを返します。
これは実際の問題につながります。customer
とoriginalCustomer
は同じインスタンスを参照することがあります。その場合、customer.Name
はoriginalCustomer.Name
と等しくなり、データベースと異なるかどうかを検出することはできません。
アイデンティティマップの設計パターンのため、ほとんどの他のORMでも同じ問題が発生していると思います。
これはどのように解決できますか?私は何とかEFに常に顧客クラスの新しいインスタンスを与えるように強制できますか?
代わりにコードをリファクタリングする必要がありますか?誰もがこのシナリオの良いデザインパターンを知っていますか?
?また、あなたの文脈の生涯は何ですか? – ken2k
ああ、申し訳ありません。 GetCustomerByIdは、DbSet .Find()のラッパーメソッドです。有効期間はHTTP要求ごとです。 –
jhu
'Name'が変更されないようにするには、上位層のコードが' Customer'エンティティ(= 'Name'が読み込み専用になる新しいクラスを作成する)で動作することを許可しないでください。 –