関係を考える:Entity Frameworkの:ChildCollection項目の削除
人1 - *のTelephoneNumber
(人は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());
}
}
これは、既に作成された私はこれが本当であることを知っています)Person(ID = 7)はTelephoneNumberコレクション内に1つのTelephoneNumberを持ちます。これは正常に動作します。
私はテストの一環として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;
}
私はこの時点で永続化コレクションにインメモリの和解でこの記事をそらすためにしたくないが、あなたを描画したいと思います既存の人の勉強への注意。この人は、これをデバッグするときにTelephoneNumberのコレクションから既にTelephoneNumberを削除しています。
これは、TestMethodの同じエンティティコンテキスト内にあるためです。 TelephoneNumberの読み込みとアイテムの削除の間に新しいコンテキストを作成した場合、取り出されたPersonはTelephoneNumbersコレクションに期待通りのTelephoneNumberを持ちます。
EntityFrameworkは明らかに変更をキャッシュしており、内部コンテキストへの変更を(より良い言葉のために)「投影」しています。私はこれが起こることを望んでいない。
どうすればこの現象を防ぐことができますか?すなわち、私がデータベースコンテンツを求めるとき、EFのDBコンテンツの印象ではなく、データベースコンテンツを欲しいと思います。
私にはあなたの質問はXY問題のようです:あなたはXを達成してYを使って解決しようとしますが、Yはうまくいかず、なぜYが動かないのか、Yを変更して作業。あなたがXに答えると( 'Save'メソッドで未変更の人をロードする目的は何かを説明してください)、より良い答えを得るかもしれません。 – Slauma
申し訳ありませんが、私はあまりにも明確なコードの邪魔な要素を排除していないようです。SopEntitiesの結果からexistingPersonを返すように見えますが、欠落しているコードの一部は、すでに存在するエンティティのイベントで返されたオブジェクトを更新しています。 しかし、これは問題ではありません。問題は、Person.TelephoneNumbersコレクションからTelephoneNumberを削除し、それを送信するとObjectContextから削除されるため、保存中に相違点を調整できないことです。 私のリポジトリパターンが壊れていないと思われます。ご協力いただきありがとうございます。 –