2013-01-24 269 views
0

考慮下面的例子中如何檢測實體存在:實體框架:的DbContext:在數據庫

public class Parent 
{ 
    public Guid ID {get;set;} 
    public string Name {get;set;} 
    public Child Child {get;set;} 
} 


public class Child 
{ 
    public Guid ID {get;set;} 
    public string Name {get;set;} 
} 

我要救一個父對象實例,用分配給它的子實例。這裏的事實是:在給定的子對象已存在於數據庫中,

Parent p = new Parent(); 
p.ID = Guid.NewGuid(); 

// Get the Child Object 
Child c = GetTheChild(...); 
p.Child = c; 

SaveParent (p); 

在功能上保存父,下面的代碼實現:

public void SaveParent (Parent p) 
{ 
    using (MyContext context = new ClinicContext()) 
    { 
     context.Parents.Add(P); 
     context.SaveChanges(); 

    } 
} 

現在問題就來了:因爲在這個孩子例子已經存在於數據庫中,但是當在上下文DBSet中添加父項時,給定的實體c也保持「已添加」的輸入狀態,猜測什麼? DBContext嘗試保存另一個帶有重複鍵的子記錄!

任何機構都知道如何解決這個問題?我在想如果實體框架可以檢測到數據庫中已經存在的記錄,是否有辦法將Insert插入到Update中。

感謝您的幫助。

回答

0

如果添加實體,則會添加所有相關的實體。如果附加實體,則所有相關實體都將被附加。在你的情況下,你想添加父實體,然後附加子實體。你也可以嘗試使用外鍵並添加父項,並將外鍵設置爲相關的子標識。這樣您就不必將實體帶到客戶端來創建關係(但您需要知道相關實體的關鍵)。

0

你最近怎麼樣?應該將孩子附加到您保存父母的相同環境中。

我的猜測是你的GetTheChild功能使用新的上下文 - 當你回來時孩子分離,併爲所有意圖和目的EF人物其被「添加」

正如專家小組說,你可以添加一個外,這意味着鍵,只需設置孩子的鑰匙而不是孩子本身,但似乎有一些設計問題需要解決。

0

我猜GetTheChild()會從數據庫中返回一個孩子。因此,您只需調用ChangeObjectState方法即可在調用SaveChanges之前將該子標記爲Unchanged。

var osm = context.ObjectStateManager; 
osm.ChangeObjectState(child, EntityState.Unchanged);