Reputation: 5550
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.
These are my main classes where notifier
is a 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. 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
Upvotes: 0
Views: 425
Reputation: 10014
When you update an existing entity, before you make changes the entity already has NotifierType (navigation property) and NotifierTypeID populated. 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. 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.
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:
notifier.MyCaseID = MyCaseID;
notifier.NotifierType = null;
notifier.NotifierTypeID = notifierView.NotifierTypeID;
Hope that helps!
Upvotes: 2