简体   繁体   English

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

[英]Updating a detached entity in Entity Framework with related entites

I am developing a solution using EF 5 in VS 2012 and I am puzzled about the correct way to specify entity relationships when adding and updating an entity. 我正在VS 2012中使用EF 5开发解决方案,我很困惑在添加和更新实体时指定实体关系的正确方法。

These are my main classes where notifier is a person : 这些是我的主要类, notifier是一个person

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; }        
}

Notifiers belong to cases 通知者属于案例

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

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

and have a type: 并有一个类型:

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

I am exposing the foreign keys between notifiers and cases and notifier types. 我在通知程序和案例以及通知程序类型之间暴露外键。

The method I use to add/update a notifier is: 我用来添加/更新通知程序的方法是:

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;
}

I am puzzled by the line after the comment **** the puzzling line **** above. 在评论**** the puzzling line ****上面**** the puzzling line ****后,我感到困惑。 I am specifying the foreign keys explicitly and don't need the this line if I am adding a notifier but I do need it if I am updating the object, otherwise it throws an exception. 我明确指定外键,如果我要添加通知程序,则不需要此行,但如果我更新对象,我确实需要它,否则会抛出异常。

The exception is 例外是

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.

Can anyone please explain why this line is needed at all. 任何人都可以解释为什么需要这一行。 Thanks 谢谢

When you update an existing entity, before you make changes the entity already has NotifierType (navigation property) and NotifierTypeID populated. 更新现有实体时,在进行更改之前,实体已经填充了NotifierType(导航属性)和NotifierTypeID。 If you then change NotifierTypeID but don't update NotifierType, Entity Framework detects a potential inconsistency (NotifierTypeID != NotifierType.NotifierTypeID) and throws the exception you are getting. 如果您随后更改了NotifierTypeID但未更新NotifierType,则Entity Framework会检测到潜在的不一致性(NotifierTypeID!= NotifierType.NotifierTypeID)并抛出您获得的异常。 This is why you need to set both when updating. 这就是您需要在更新时设置两者的原因。 When adding, you don't have this issue because only one of the IDs is defined (NotifierTypeID, but not NotifierType.NotifierTypeID), so it just uses that one. 添加时,您没有此问题,因为只定义了其中一个ID(NotifierTypeID,而不是NotifierType.NotifierTypeID),所以它只使用那个。

If you want to avoid going to retrieve the notifier type for updates, you should be able to just set it to null instead, and in that case there will be no discrepancy and it can just use the NotifierTypeID that you set: 如果您想避免检索更新的通知程序类型,您应该只能将其设置为null,并且在这种情况下不会出现差异,它只能使用您设置的NotifierTypeID:

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

Hope that helps! 希望有所帮助!

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM