0

鉴于关系:

第 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());
        }
    }

它获得了一个已经创建的(我知道这是真的)Person (ID=7),它的 TelephoneNumbers 集合中有一个 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;
        }

在这一点上,我不想用内存与持久集合的协调来分散这篇文章的注意力,但想提请您注意现有人员的试用。当我通过此调试时,此人已经从其 TelephoneNumbers 集合中删除了 TelephoneNumber。

原因是它在 TestMethod 中的相同实体上下文中。如果我在加载 TelephoneNumber 和删除项目之间创建一个新上下文,则检索到的 Person 确实在 TelephoneNumbers 集合中具有预期的 TelephoneNumber,以便在适当的时候删除。

EntityFramework 显然正在缓存更改并将更改“投影”(为了更好的词)到内部上下文中。我不希望这种情况发生。

我怎样才能防止这种行为?IE。当我询问数据库内容时,我想要数据库内容而不是 EF 对数据库内容的印象。

4

1 回答 1

0

您可以尝试加载此行中的人员...

Person existingPerson= SopEntities.People....
    .SingleOrDefault(q => q.ID==person.ID);

...禁用更改跟踪(使用AsNoTracking()forDbContextMergeOption.NoTrackingfor ObjectContext)以避免 EF 尝试将实体附加到您已经修改它的上下文。

SavePerson如果您想使用从返回的对象进行更改跟踪并希望将其附加到上下文,这可能没有用。EF 不允许有两个具有相同键的附加对象,它将返回已附加的对象,包括您已应用于实体的所有修改。

我不知道你想达到什么目的。它看起来有点像您的SavePerson方法应该返回“以前的”人(修改之前的状态的人)。如果是这样,另一种方法是在开始修改对象之前(深度)克隆对象并返回克隆。

于 2012-04-27T17:00:03.790 回答