2013-10-11 140 views
0

我正在開發一個在VS 2012中使用EF 5的解決方案,我對添加和更新實體時指定實體關係的正確方式感到困惑。更新實體框架中的分離實體以及相關實體

這是我的主要類別,其中notifierperson

public class Notifier : Person 
{ 
    public bool IsValid { get; set; } 
    public int NotifierTypeID { get; set; } 
    public virtual NotifierType NotifierType { get; set; } 
    public int MyCaseID { get; set; } 
    public virtual MyCase MyCase { get; set; } 
} 

public abstract class Person 
{ 
    public int PersonID { get; set; } 
    public String Name { get; set; }   
} 

通告屬於個案

public class MyCase 
{ 
    public int MyCaseID { get; set; }   

    public DateTime DateOfNotification { get; set; } 
    public virtual ICollection<Notifier> Notifiers { get; set; }   
} 

又有型:

public class NotifierType 
{ 
    public int NotifierTypeID { get; set; } 
    public string NotifierTypeName { get; set; } 
} 

我露出了國外通知者和案例與通知器類型之間的關鍵字。

我使用的方法添加/更新通知是:

using (MyContext dbContext = new MyContext(connectionString)) 
{ 

    notifier.MyCaseID = MyCaseID; 
    notifier.NotifierTypeID = notifierView.NotifierTypeID; 

// **** the puzzling line **** 
    notifier.NotifierType = dbContext.NotifierTypes.Find(notifierView.NotifierTypeID); 

    //dbContext.Database.Log = s => System.Diagnostics.Debug.Write(s); 
    dbContext.Entry(notifier).State = notifier.PersonID == 0 ? EntityState.Added : EntityState.Modified; 

    dbContext.SaveChanges(); 

    // save the ID in case it's new 
    notifierViewReturn.PersonID = notifier.PersonID; 
} 

我對線以上的評論**** the puzzling line ****後不解。我明確指定外鍵,如果我添加通告程序,則不需要此行,但如果我正在更新對象,則確實需要它,否則會引發異常。

唯一的例外是

Message=A referential integrity constraint violation occurred: 
The property values that define the referential constraints are not 
consistent between principal and dependent objects in the relationship. 

誰能請解釋爲什麼需要在所有的這條線。謝謝

+0

你應該發佈拋出的異常。從這個角度來看,你可能會猜到接下來你需要看什麼(也就是說,在你習慣了EF例外的意思之後)。 – rliu

+0

嗯。這可能稍微不相關,但我對'Notifier'的PK有點困惑。我認爲它是'PersonID',除了你也有一個'EditedByID = thisUser.PersonID' ...那些PK是同一個表嗎?另外,您是否可以確認'Notifier'和'NotifierType'之間的FK是否在數據庫的'Notifier'表中? – rliu

+0

Hi Roliu。是的PK是PersonID - 我已經刪除了EditById,因爲它是無關緊要的。 FK在數據庫中。 –

回答

2

當您更新現有實體時,在您進行更改之前,實體已經具有NotifierType(導航屬性)和NotifierTypeID填充。如果您然後更改NotifierTypeID但不更新NotifierType,則實體框架檢測到潛在的不一致(NotifierTypeID!= NotifierType.NotifierTypeID)並引發您獲得的異常。這就是爲什麼你需要在更新時同時設置。添加時,您沒有此問題,因爲只定義了其中一個ID(NotifierTypeID,但不是NotifierType.NotifierTypeID),因此它只使用該標識。

如果您想要避免檢索更新的通知程序類型,您應該可以將其設置爲null,並且在這種情況下不會有差異,並且可以使用您設置的NotifierTypeID:

notifier.MyCaseID = MyCaseID; 
notifier.NotifierType = null; 
notifier.NotifierTypeID = notifierView.NotifierTypeID; 

希望有所幫助!

+0

多麼完美的答案,非常感謝,非常感謝。對不起,我只能給你一票。 –

+0

我很困惑爲什麼'NotifierType'甚至被加載。它不應該是懶惰加載,因此是'空',除非訪問? – rliu