2012-04-27 66 views
0

給出的關係:實體框架: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()); 
     } 
    } 

其中獲得已經創建(an d我知道這是真實的)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; 
     } 

我不想分心這個帖子在內存中,以持久的集合在這一點上的和解,但希望能引起您的關注現有人的發現。當我對此進行調試時,此人已將TelephoneNumber從TelephoneNumbers集合中刪除。

原因是它在TestMethod中的相同Entities上下文中。如果我在加載TelephoneNumber和刪除項目之間創建新的上下文,則在適當的時候,檢索到的Person在TelephoneNumbers集合中具有預期的TelephoneNumber以供刪除。

EntityFramework顯然緩存了這個變化,並且將這個變化「投射」到了一個更好的單詞中。我不希望發生這種情況。

如何防止此行爲?即。當我詢問數據庫內容時,我想知道數據庫內容,而不是EF對數據庫內容的印象。

+0

對我來說,你的問題看起來像一個XY問題:你想達到X並嘗試通過Y解決它,但Y不工作,你問爲什麼Y不工作,你如何改變Y使它工作。如果你問X(解釋,用'Save'方法加載未修改人的目的是什麼),你可能會得到更好的答案。 – Slauma 2012-04-27 17:06:19

+0

對不起,我不清楚代碼中分散注意力的元素。它*看起來像我從SopEntities結果返回existingPerson,但缺少的部分代碼是我正在更新在已存在的實體中返回的對象。 但這不是問題所在。問題是從Person.TelephoneNumbers集合中刪除TelephoneNumber,然後提交它將它從ObjectContext中刪除,所以我無法調和保存期間的差異。 我懷疑我的存儲庫模式不合格。謝謝你的幫助。 – 2012-04-30 09:16:29

回答

0

你可以嘗試加載人在這個行...

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

...有殘疾的變化跟蹤(使用ObjectContextAsNoTracking()DbContextMergeOption.NoTracking),以避免EF嘗試附加實體到你已經修改它的上下文。

如果要使用從SavePerson返回的對象進行更改跟蹤並希望將其附加到上下文,則這可能毫無用處。 EF不允許使用同一個鍵擁有兩個連接的對象,它將返回已經連接的對象,包括已經應用到實體的所有修改。

我不知道你想達到什麼目的。它看起來有點像你的SavePerson方法應該返回「之前」的人(在你修改它之前處於狀態的人)。如果是這樣,另一種方法是在開始修改它並返回克隆之前(深)克隆該對象。