.Net 4.0 Beta 2 Entity Framework – Many To One and POCO / INSERT statement conflicted with the FOREIGN KEY constraint issue

So the next step in the New Entity Framework saga was to make a many to one relationship and get it to save. After all, with the last version I had far more issues with many to one than any other kind of relationship. Turns out, the steak is still in tact.

Taking the structure from the last post, I added an AdType. It’s very simple. Columns are AdTypeId (Int Primary) and Description (Varchar). I added a AdTypeId column to the Ad table and created a foreign key to the AdType table with it.

Basically Many Ads to One AdType.

Then I did the usual Update Model From Database with the .edmx file. Same old same old. Well this added the AdType class and the relationship:

AddAdtype

So far, so good. Now with this it also means that I need to create the AdType class and add the AdType property to the Ad class along with the AdTypeId property.

Side Note:

Far as I can tell, you need the AdTypeId property despite also having the AdType property. Don’t forget this.

Here’s the AdType class:

  public class AdType
  {
    public Int32 Id { get; set; }
    public String Description { get; set; }

    public virtual IList<Ad> Ads { get; set; }
  }

And on the Ad class I had to “Ad” (HARHRHARHR) the AdType property along with the AdTypeId property:

  public class Ad
  {
    public Int32 Id { get; set; }
    public DateTime CreatedDate { get; set; }
    public String Name { get; set; }
    public DateTime? LastUpdated { get; set; }
    public Int32 Height { get; set; }
    public Int32 Width { get; set; }

    //Interesting note: Works even if this is private and non virtual
    private Int32 AdTypeId { get; set; }

    public virtual AdType AdType { get; set; }
    //Note:
    //If properties are to be lazy loaded, must be virtual
    public virtual IList<Newpaper> Newspapers { get; set; }
  }

Classes are done. Should be good to go right? WRONG YOU ARE SO F-ING WRONG! Just try this, I dare you:

   Ad ad = new Ad();

   ...
   ad.AdType = someAdType();
   context.Ads.Add(ad);
   context.SaveChanges();

DUN DUN DUUUUN INSERT statement conflicted with the FOREIGN KEY constraint.

You try it? Idiot. You just got stuffed by a foreign key error. Why? Well The Big M has an answer:

In this example, Customer is a pure POCO type. Unlike with EntityObject or IPOCO based entities, making changes to the entity doesn’t automatically keep the state manager in sync because there is no automatic notification between your pure POCO entities and the Entity Framework. Therefore, upon querying the state manager, it thinks that the customer object state is Unchanged even though we have explicitly made a change to one of the properties on the entity.

Basically because these objects aren’t really being watched by the State Manager, it has no idea anything has changed and should be persisted. Therefore, it has no idea that the AdType property has changed and that the AdTypeId should be updated to reflect this. That’s right, it just ignored the AdType property and left the AdTypeId to it’s default… 0 (That’s a Zero or as the English say, Zed). How do you get around this? This little option.

  context.SaveChanges(System.Data.Objects.SaveOptions.AcceptAllChangesAfterSave);

This tells it to persist the changes that it didn’t know about. Now I’m still picking this up as I go so bare with me as I might have the best explanations yet on why things work with the New Entity Framework. Then again, this is a site by a tool.

6 thoughts on “.Net 4.0 Beta 2 Entity Framework – Many To One and POCO / INSERT statement conflicted with the FOREIGN KEY constraint issue”

  1. it worked with AcceptAllChangesAfterSave option instead of DetectChangesBeforeSave? weird. i’m chasing down something similar, am curious to see if this fixes my issue.

    1. Pretty sure I tried DetectChangesBeforeSave in fact because it seems oddly logical. Sometimes I find Entity Framework like a Mac, do what you think it logical and then try the exact opposite.

      1. i’m still not sure how the ID gets properly updated correctly based on …After… instead of …Before… (and actually, I have no idea for sure if it was the source of my problem — it’s such a specific case with so many environment variables, it’s ridiculous), BUT i did notice that using …After… instead of …Before… forces the POCO to be a straight POCO, rather than using EF proxies for change tracking, if enabled.

        Which makes sense, if you save after changes, then there should be no proxies to keep track of anything.

        EF4 is really cool, but it’s required a fair amount of digging around and figuring things out on my own so far. then again, it is in beta2, so maybe i should lay off a bit… =)

        thanks for the help, btw!

  2. Dude, the English don’t say Zed for Zero. Us Australians and the English say ‘zero’ or ‘nought’, just as you do (if you say nought that is). We say ‘zed’ for the last letter of the alphabet. That shouldn’t be too hard to work out from the context. Just sayin’

    1. Well I’ve heard such things in american movies and as we all know, american movies always paint a perfect picture of other cultures. So you sir, are in the wrong.

Comments are closed.