2013-06-19 119 views
5

幾個星期前我剛開始一個新項目,並決定給EF Code First一個試試看, 我之前使用過NHIbernate,並且我非常喜歡有ORM out-of-the-從MS那裏鞠躬,迄今爲止它一直很棒 - 直到我開始製作複雜的物體。EF vs Nhibernate Merge斷開對象圖

我的項目級別如下: Azure WCF角色 - 用EF Code First處理DAL。 與Knockout MVC 4 Azure WebSite角色 - 處理客戶端。 (我創建了WCFRole的未來,我們需要訪問來自不同平臺的服務)

下面是我遇到的麻煩很基本的EF的Code First設計: - 我只轉移服務和站點之間的DTO,並且製作了一個通用映射器來映射內部DTO(如果存在的話)。 - 我有一張城市桌子和一個帶有城市物業的地址對象(我們需要城市作爲特殊功能的財產,而不僅僅是名稱)

客戶端知道城市列表,並返回一個新地址與現有的城市 當我嘗試添加新的地址,一個新的城市與舊的現有數據創建一個新的城市,我已經得到這種情況發生,因爲EF不知道如何合併斷開的對象,從我讀的不支持任何合併,並且簡單的不那麼舒服的解決方案只是管理對象狀態 - 將City對象狀態更改爲Unchanged。

但有一個大的複雜分貝設計處理這聽起來很可怕

我的問題 - 什麼是處理這個最佳實踐/簡單的方法? 我想過的解決方案 - 重寫SaveChanges方法通過所有對象,如果ID不爲null/0 /其他約定將其從添加到未更改 - 可以解決這個問題嗎?

我的第二個問題 - ,因爲我有很多的經驗與NHibernate(帶連接的對象) - 我想知道這個是什麼NHibernate的時間?我讀過NHibernate確實有一個AutoMagic合併功能來重新連接斷開的複雜對象,這是真的嗎?我的基本斷開連接的地址 - >城市設計將與AutoMagic Merge開箱即用嗎? 使用它的後果是什麼?

非常感謝:)

更新:這個問題的簡化代碼。

public class Address 
{ 
    public int ID { get; set; } 

    public virtual City City { get; set; } 
} 

public class City 
{ 
    public int ID { get; set; } 

    public string Name { get; set; } 
    public virtual Zone Zone { get; set; } 
} 

public class MyContext : DbContext 
{ 
    public MyContext() : base("TransportService") { } 

    public virtual DbSet<City> Cities { get; set; } 
    public virtual DbSet<Address> Addresses { get; set; } 

    protected override void OnModelCreating(DbModelBuilder modelBuilder) 
    { 
     base.OnModelCreating(modelBuilder); 

     modelBuilder.Entity<Address>() 
      .HasRequired(x => x.City) 
      .WithMany().WillCascadeOnDelete(true); 

    } 
} 

添加新地址:

public void Add(AddressDto address) 
    { 
     using (var context = new MyContext()) 
     { 
      context.Addresses.Add(address.FromDto<Address>()); 

      context.SaveChanges(); 
     } 
    } 

的「FromDto」是通用的映射器擴展,它創建的所有信息的新地址,包括市(和City.ID屬性)

這將導致創建一個新的城市,而不是使用對舊城區的引用。

+1

如果你顯示一些代碼來演示你的問題,回答這個問題會容易得多。 EF可以合併斷開的對象,它有一個名爲_relationship fixup_的後臺進程,但沒有代碼,很難判斷這是否對您有幫助。 –

+0

我給了基本的設計,我會添加代碼。 –

+1

從我讀到關於關係修復的內容 - 它是手動重新連接,並且它只在當前上下文具有所有要重新連接的對象時才起作用。 Nhibernate通過主鍵Key自動合併,這個特性爲大型複雜對象節省了很多麻煩,EF甚至不是這些項目中的候選對象,你只需要3-4層內部對象,並且保持與上下文的連接將開始在獨立的環境中穿上你... –

回答

3

我發現,EF沒有自動合併,其合併功能至今都只能手動合併,如果上下文對象在內存中具有對象的所有依賴它只會工作。

處理多層斷開連接的對象,並處理手動重新連接它們是很多工作,並且可能導致很奇怪和難以處理的錯誤(就像問題中提到的創建新城市的原因那樣,所以它只是創建了一個新的即使它有一個ID)

所以現在-Nhibernate贏得了這場戰鬥,它,並取得成功(從我的經驗) 這是一個更多的東西比EF運行的東西,但它是值得的麻煩。

+2

我同意。對Entity Framework來說,這是一個很大的遺憾。是的,它需要一些「調整」才能讓NHibernate獲得正確的結果,但哇,通過.Merge()和B00M運行它!你完成了。感謝您跟進您的問題......現在我知道我並不瘋狂。 – granadaCoder

+0

這是一個很好的鏈接,可以顯示「手動跟蹤」是如何發生的......這個鏈接是用於「斷開」的:::: http://www.entityframeworktutorial.net/EntityFramework4.3/delete-entity-using -dbcontext.aspx – granadaCoder

+0

E7能否更好地支持斷開連接的實體? – HappyNomad