我正在努力與實體框架代碼第一次合併。 我有一個通用資源庫的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會更改名稱,但不適用於子項。有沒有其他方法可以做到這一點?對我來說,似乎有點吱吱,我不得不手動滾動此功能
嗨盧克,感謝您的信息,但我不應該從存儲庫檢索實體,修改它,然後提交它只是因爲它的EF。我的假設是SetValues基本上會對所有屬性進行遞歸比較,並將任何屬性分配給不匹配的跟蹤實體。至於引發錯誤的註釋掉的代碼,該對象未被附加(參見主代碼塊下方的變更跟蹤器調用),並且它們也沒有任何子屬性,因爲該實體已經完全從頭開始創建,但錯誤仍然存在發生。 – Dylan 2012-02-24 15:37:58
如果要創建全新實體,常規方法是使用Routines.Add(myNewRoutine),attach用於重新連接已存在於數據庫中但尚未加載到對象圖上的對象。 – 2012-02-25 01:12:45
Hi Luke, 我特意遺漏了一些代碼,但我有一個調用Routines.Add(item)的插入方法;沒有問題。這只是爲了處理更新場景 – Dylan 2012-02-25 01:48:27