与えられた関係:
個人 1 -- * 電話番号
(個人には 0、1、またはそれ以上の TelephoneNumber エンティティがあります)
そして私の統合テスト:
[TestMethod()]
public void DeleteTelephoneNumberAndSavePersonTest()
{
Person person;
using (SopEntities sopEntities = EntitiesFactory.Create(Properties.Resources.ConnectionString))
{
PeopleRepository target = new PeopleRepository(sopEntities);
person = target.GetPerson(7);
Assert.IsTrue(person.TelephoneNumbers.Any());
Assert.AreEqual("DeleteTelephoneNumberAndSavePersonTest", person.TelephoneNumbers.Single().Number);
person.TelephoneNumbers.Remove(person.TelephoneNumbers.Single());
target.SavePerson(person);
Person savedPerson = target.GetPerson(7);
Assert.IsFalse(savedPerson.TelephoneNumbers.Any());
}
}
これは、TelephoneNumbers コレクションに単一の TelephoneNumber を持つ、既に作成されている (これが正しいことを知っている) Person (ID=7) を取得します。これはうまくいきます。
次に、テストの一環として TelephoneNumber を削除します。
次のコードを使用して保存します。
public Person SavePerson(Person person)
{
if (person == null)
throw new ArgumentNullException("person");
Person existingPerson= SopEntities.People.Include("EmailAddresses").Include("TelephoneNumbers").Include("WebResources").SingleOrDefault(q => q.ID==person.ID);
// NOTE: The existingPerson ALREADY has the TelephoneNumber removed, even though retrieved from the DB again. WHY IS THIS?
// snip: collection reconciliation code
SopEntities.SaveChanges();
return existingPerson;
}
この時点で、インメモリから永続化されたコレクションへの調整でこの記事の注意をそらしたくはありませんが、existingPerson のトリビュールに注意を向けたいと思います。これをデバッグすると、この人はすでに TelephoneNumbers コレクションから TelephoneNumber を削除しています。
これは、TestMethod の同じエンティティ コンテキスト内にあるためです。TelephoneNumber の読み込みとアイテムの削除の間に新しいコンテキストを作成すると、取得された Person には、やがて削除される TelephoneNumbers コレクションに予期される TelephoneNumber が含まれます。
EntityFramework は明らかに変更をキャッシュしており、変更を内部コンテキストに "投影" (より適切な言葉が必要なため) しています。私はこれが起こることを望んでいません。
どうすればこの動作を防ぐことができますか? すなわち。データベースの内容を尋ねるとき、DB の内容に対する EF の印象ではなく、データベースの内容が必要です。