2013-11-01 56 views
0

我使用實體框架(EF),5守則第一其它外鍵關係。實體框架5加實體和子實體與

我有一個自我參照的對象,我們稱之爲Demo

public class Demo 
{ 
    public int Id; 
    public string Name; 
    public Demo Parent; 
    public ICollection<Demo> Children; 

    public Item Item; 
} 

這有一個參考的另一個目標,Item

public class Item 
{ 
    public int Id; 
    public string Name; 
    public Item Parent; 
    public ICollection<Item> Children; 
} 

是的,這也是自引用的,但這應該不重要。該數據庫目前擁有基於這是由數據庫遷移添加到Demo表的Item_Id的外鍵。數據庫預填充了一組Item記錄(這是一個有限的集合)。

我的背景已經很好地映射到這個數據庫,我做的新記錄大量數據的插入。還有一些代碼是用數據填充對象的。這是通過EF實際進口:

public void ImportDemo(IEnumerable<Demo> demos) 
{ 
    var context = this.UnitOfWork.MyApplicationContext; 

    foreach (var demo in demos) 
    { 
     this.DataSet.Add(demo); 
     context.Entry(demo).State = EntityState.Added; 
    } 

    // NOTE: expecting an empty db. 
    context.SaveChanges(); 
} 

我DbModelBuilder有以下幾點:

modelBuilder.Entity<Demo>() 
       .HasOptional(p => p.Parent) 
       .WithMany(p => p.Children); 

    modelBuilder.Entity<Item>() 
       .HasOptional(p => p.Parent) 
       .WithMany(p => p.Children); 

我可以導入Demo實體成功,孩子Demo實體,但每個孩子的Demo實體在數據庫是創建一個新Item而不僅僅是連接到現有Item。父Demo實體沒有Item記錄,它們爲空。

如何確保子女Demo實體鏈接到現有的Item記錄而不是創建新記錄?

+1

我不認爲你在這裏顯示有問題的代碼,我認爲一旦你證明實例爲您導入功能參數演示對象的代碼就會出現問題。 –

+0

感謝@ArturoMartinez'的評論我能夠正確地關注問題,並且我添加了一個答案。 – Boggin

回答

0

整個結構是建立在業務層和映射(AutoMapper)有問題的車型。

Item對象位於DbContext.IDbSet<Item>.Local集合中,但模型中的虛擬Items需要使用本地集合中的Item對象進行重置,如下所示。

public void ImportDemo(IEnumerable<Demo> demos) 
{ 
    foreach (var demo in demos) 
    { 
     foreach (var child in demo.Children) 
     { 
      child.Item = 
       dbContext.Items.Local.First(p => p.Id == child.Item.Id) 
     } 

     dbContext.Set<Demo>.Add(demo); 
    } 

    dbContext.SaveChanges(); 
} 

我嘗試使用Attach()但它並沒有表現我沒有料到它從MSDN文檔。