C# 使用相关实体更新实体框架中分离的实体

C# 使用相关实体更新实体框架中分离的实体,c#,entity-framework,C#,Entity Framework,我正在VS 2012中使用EF 5开发一个解决方案,我对添加和更新实体时指定实体关系的正确方法感到困惑 这些是我的主要类,通知程序是一个人: public class Notifier : Person { public bool IsValid { get; set; } public int NotifierTypeID { get; set; } public virtual NotifierType NotifierType { get; set; } p

我正在VS 2012中使用EF 5开发一个解决方案,我对添加和更新实体时指定实体关系的正确方法感到困惑

这些是我的主要类,
通知程序
是一个

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; }        
}
我正在公开通知程序与案例和通知程序类型之间的外键

我用于添加/更新通知程序的方法是:

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;
}
我对上面的注释后面的那行感到困惑。我显式地指定外键,如果添加通知程序,则不需要this行,但是如果更新对象,则需要this行,否则会引发异常

例外是

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.

有人能解释一下为什么需要这条线吗。当您更新现有实体时,在进行更改之前,该实体已经填充了NotifierType(导航属性)和NotifierTypeID,非常感谢。如果随后更改NotifierTypeID但不更新NotifierType,则实体框架会检测到潜在的不一致性(NotifierTypeID!=NotifierType.NotifierTypeID),并抛出所获得的异常。这就是为什么在更新时需要同时设置两者的原因。添加时,不会出现此问题,因为只定义了一个ID(NotifierTypeID,但不定义NotifierType.NotifierTypeID),所以它只使用该ID

如果要避免检索更新的通知程序类型,则应将其改为null,在这种情况下不会出现差异,并且可以使用您设置的NotifierTypeID:

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

希望有帮助

您应该发布抛出的异常。从这一点上,你可能可以猜出你接下来需要看什么(好吧,也就是说,在你习惯了EF异常的含义之后)。这可能有点无关紧要,但我对
通知程序的主键有点困惑。我假设它是
PersonID
,除了您还有一个
EditedByID=thisUser.PersonID
。。。那些PK是同一张桌子的吗?另外,您能否确认
通知程序
通知类型
之间的FK是否在数据库的
通知程序
表中?您好。是的,PK是PersonID-我已经删除了EditById,因为它不相关。FK在数据库中。多么完美的答案,非常感谢和感谢。对不起,我只能给你一票。我不明白为什么要加载
NotifierType
。它不是应该是延迟加载的,因此除非被访问,否则它应该是
null
notifier.MyCaseID = MyCaseID;
notifier.NotifierType = null;
notifier.NotifierTypeID = notifierView.NotifierTypeID;