3

I'm working with Entity Framework 6 Code First and Fluent API. I have a one to many relationship between Visit and VisitPage (1 Visit has many VisitPage objects). This is the simplified version of the POCO classes:

Visit: Id (identity), UrlReferrer, Pages. VisitPage: Id (identity), Name, Visit, VisitId

First, I create a Visit object and add a VisitPage object to it. Then, I insert them into the DB. Until this point everything works OK. Observation: VisitId property in VisitPage is automatically set after insertion (it takes the identity value from DB and sets the property).

Then, in a disconnected environment, I add a new page to the visit (I don't get the Visit object from the DB, that's what I mean by disconnected environment). This new page is referring the same visit object but I'm not setting the VisitId property because I think that EF should set it based on the Visit property. And that's the problem, EF doesn't set it and, in fact, it throws an exception saying that the value of Visit property and VisitId property doesn't match. I was expecting that EF was going to be able to do this under the hood (in the DetectChanges method for example) but it doesn't.

Exception message:

A referential integrity constraint violation occurred: The property value(s) of 'VisitId' on one end of a relationship do not match the property value(s) of 'VisitPage.VisitId' on the other end.

So, how do I solve this? I see two possible solutions: 1) Work in a connected environment --> get the Visit object from EF and then add the page object. In this case EF updates VisitId value and it works. 2) Set VisitId manually after setting the Visit object.

I hope I've been clear enough. If not, please let me know.

Francisco Goldenstein
  • 13,299
  • 7
  • 58
  • 74

1 Answers1

6

Either do this

visitPage.VisitId = VisitPage.Visit.Id;
visitPage.Visit = null;

or

context.Visits.Attach(visitPage.Visit);

or

context.Entry(visitPage.Visit).State = EntityState.Unchanged;
Yuliam Chandra
  • 14,494
  • 12
  • 52
  • 67
  • I'm sorry, maybe I'm missing something. 1st option: why would I set the visitPage.Visit to null? If I'm gonna be explicit (something that I didn't want), I would set the visitPage.VisitId = visitPage.Visit.Id because I had already set visitPage.Visit = visit; Regarding the second option, attach will set the state to unchanged, just like the 3rd option you proposed. After calling SaveChanged nothing is gonna be sent to the DB (no update). You can check http://msdn.microsoft.com/en-us/data/jj592676.aspx. Thanks for the answer but I hope that there's a better solution. – Francisco Goldenstein Jul 30 '14 at 14:01
  • @FranciscoGoldenstein, `visitPage` is in the added state, sync won't work unless you attach or update the state it manually, otherwise you need to use the foreign key value, in this case `VisitId`, take a look [here](http://msdn.microsoft.com/en-us/data/jj713564.aspx) `Note: If the reference is in the added state (in this example, the course object), the reference navigation property will not be synchronized...` – Yuliam Chandra Jul 30 '14 at 14:33