C# 使用相关实体更新实体框架中分离的实体
我正在VS 2012中使用EF 5开发一个解决方案,我对添加和更新实体时指定实体关系的正确方法感到困惑 这些是我的主要类,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
通知程序
是一个人
:
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;