Entity Framework 6 adding new navigation entity causing "cannot insert explicit identity" error

StackOverflow https://stackoverflow.com/questions/23665455

  •  22-07-2023
  •  | 
  •  

سؤال

-----edit-----

I have my code working now. I tried making the relationship one-to-many and it works now by using:

newInspection.Sites.Add(newSite)

The Unique Key constraint is still present in the database, so I'm not completely comfortable with this as being the "answer" since it's more of a work around. I have no idea how to make the one-to-one work, as every time I have tried it (with other tables too for testing purposes) it always gives me this error.

----/edit-----

I am using EF 6 Code First for an application I am developing. I used the EF 6.1 tools to reverse engineer the code first model. I am running into a problem with a 1-to-1 relationship when trying to add new items to the database.

Here is the object that's causing a problem:

[Table("childTable")]
public partial class Site
{
    [Key]
    public int siteID{ get; set; }

    public int inspectionID { get; set; }

    ...

    public virtual Inspection inspection { get; set; }
}

The main "inspection" class has a 1-to-1 relationship with the site, and the class is organized like this:

[Table("someTable")]
public partial class Inspection
{
    [Key]
    public int inspectionID { get; set; }

    ...

    public virtual Site site { get; set; }
}

The context defines this:

modelBuilder.Entity<Inspection>()
            .HasOptional(e => e.site)
            .WithRequired(e => e.inspection);

I am creating a new "Site" object and setting everything in it except the "siteID" and "inspectionID" properies -- the primary and foreign key respectively. I am adding it to a new "Inspection" object as a navigation property, then adding the "Inspection" to the context and trying to save:

        Inspection newInspection = new Inspection
        {
           ...

           site = newSite; // Constructed earlier, no explicit ID. ID = 0 if checked
        };

        using (var db = new Context())
        {
            db.Inspections.Add(newInspection);
            db.SaveChanges();
        }

When I call the SaveChanges() I get the "Cannot insert explicit value for identity column in table '--------' when IDENTITY_INSERT is set to OFF."

I cannot understand why it is doing this, so I used db.Database.Log to check out the SQL being generated, and it is trying to pass an ID for the siteID after the "Inspection" insert. That doesn't make sense to me, because if I check the siteID before calling SaveChanges() the ID is 0, as a "new" one should be. However, it is actually trying to insert a number, like 16. I am unsure where it is getting the number. I thought when adding a new item to the context (i.e. db.Inspections.Add()) that it flagged everything in there as new and treated it as such during insert.

I have no idea why it is trying to insert the ID, but it appears to do this for any navigation property that is 1-to-1. That requires setting the navigation property explicitly, as opposed to using the .Add() method. 1-to-many have always worked fine for me (and do in this Context).

Does anyone know why my DBContext is trying to pass the ID?

هل كانت مفيدة؟

المحلول

Entities that have a 1 to 1 relationship should have the same value in the primary key. That means that the primary key in the dependent should also be a foreign key to the principal, and should not be an identity field.

You should change your tables in line with that requirement so that EF can insert the Inspection object then take its new ID and insert that value into the Sites table as the foreign key/primary key.

EF will add the foreign key constraint when you migrate back to a one-to-one but you will need to add sql to the migration to remove the Identity because EF can't do that (yet)

References:

What does principal end of an association means in 1:1 relationship in Entity framework

Do I define a relationship between two entities on the dependent or the principal?

Configuring a Required-to-Optional Relationship (One-to-Zero-or-One)

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top