2012-02-24 99 views
0

我正在努力與實體框架代碼第一次合併。 我有一個通用資源庫的MVC控制器。視圖模型被貼上去的,我轉換到這一點的類型EF知道實體框架4合併數據到被跟蹤的實體

var converted = AutoMapper.Mapper.Map<RoutineViewModel, Routine>(result); 
    _routineRepository.Update(converted); 

在庫中我有:

/* 
      Routines.Attach(item); 
      ChangeTracker.Entries<Routine>().Single(x => x.Entity.Id == item.Id).State = EntityState.Modified;*/ 
      var match = Routines.Single(x => x.Id == item.Id); 
      var entity = Entry(match); 

      entity.CurrentValues.SetValues(item); 

我註釋掉的第一位,因爲它是亂扔的錯誤已追蹤的實體,即使像這樣的檢查:

if (ChangeTracker.Entries<Routine>().Count(x => x.Entity.Id == item.Id) != 0) 

返回false

我遇到的問題是Routine對象具有Steps的ICollection屬性。當我將跟蹤實體的值設置爲與poco的值相匹配時,ICollection更改不會傳播下來。環顧這個網站看起來有幾個令人討厭的遞歸調用。這真的是它的工作原理還是我錯過了什麼?

有什麼簡單的方法可以說,這裏是源對象(未跟蹤),將它的所有內容都複製到跟蹤對象中?

只是很清楚,我不認爲首先獲取對象並更新屬性應該在存儲庫之外完成。這似乎不僅強制你跨域邊界傳遞你的數據模型,而且看起來像是代替等效的SQL語句(更新x,y,其中id = 1),以便(插入臨時表中id = 1)在臨時表中更新x .....現在對於表中每一行的更新表x = tempx其中id = 1)

編輯 - 所以問題在於setValues不是遞歸調用。例程對象有2個簡單屬性(id和name)和一個complex(ICollection)。如果進入的項目名稱已更改並且某些步驟已更改,則setValues會更改名稱,但不適用於子項。有沒有其他方法可以做到這一點?對我來說,似乎有點吱吱,我不得不手動滾動此功能

回答

0

從我可以告訴你創建你的實體,填充屬性,然後將其附加到數據庫。這對EF來說有點不妥。

如果要附加一個已經在數據庫中但未被跟蹤的對象,可以使用附加,但只有在附加調用被記錄後纔會將更改提交給數據庫。如果你想使用附件,請確保在調用該方法後進行更改。

此外,EF只允許您附加當前不在對象圖中的對象。因此,如果您嘗試連接兩次相同的對象(或使用相同的鍵),您將會看到一個錯誤,例如您看到的錯誤。

+0

嗨盧克,感謝您的信息,但我不應該從存儲庫檢索實體,修改它,然後提交它只是因爲它的EF。我的假設是SetValues基本上會對所有屬性進行遞歸比較,並將任何屬性分配給不匹配的跟蹤實體。至於引發錯誤的註釋掉的代碼,該對象未被附加(參見主代碼塊下方的變更跟蹤器調用),並且它們也沒有任何子屬性,因爲該實體已經完全從頭開始創建,但錯誤仍然存​​在發生。 – Dylan 2012-02-24 15:37:58

+0

如果要創建全新實體,常規方法是使用Routines.Add(myNewRoutine),attach用於重新連接已存在於數據庫中但尚未加載到對象圖上的對象。 – 2012-02-25 01:12:45

+0

Hi Luke, 我特意遺漏了一些代碼,但我有一個調用Routines.Add(item)的插入方法;沒有問題。這只是爲了處理更新場景 – Dylan 2012-02-25 01:48:27