Question

I think I have an error in my model, but I'm not sure what it is.

First the error

The INSERT statement conflicted with the FOREIGN KEY constraint 
"FK_dbo.ProjectDocAccess_dbo.ProjectDoc_ProjectDocAccessID". The conflict 
occurred in database "dbname", 
table "dbo.ProjectDoc", column 'ProjectDocID'.

The ProjectDocAccess model (trimmed down)

public class ProjectDocAccess
{
    public int ProjectDocAccessID { get; set; }
    public int ProjectDocID { get; set; }

    public virtual ProjectDoc ProjectDoc { get; set; }
}

The ProjectDoc model (trimmed down)

public class ProjectDoc
{
    public int ProjectDocID { get; set; }
    public int ProjectID { get; set; }

    public ProjectDocAccess ProjectDocAccess { get; set; }
    public Project Project { get; set; } 
}

The fluent API mapping

        modelBuilder.Entity<ProjectDocAccess>()
            .HasRequired(p => p.ProjectDoc).WithOptional()
            .WillCascadeOnDelete(true);

When I attempt to insert a new record in the ProjectDocAccess table, it forces me to insert a value in the ProjectDocAccessID field. In all of my other models, this auto increments. I'm not sure what I am doing wrong. Help?

UPDATE

Based on the answer I selected. This is what I did to fix it.

Removed the fluent API mapping altogether.

Updated the ProjectDocAccess model as follows

 public class ProjectDocAccess
 {
    [Key, ForeignKey("ProjectDoc")]
    public int ProjectDocAccessID { get; set; }

    public virtual ProjectDoc ProjectDoc { get; set; }
 }
Was it helpful?

Solution

First, when issues like this you should take a look at your migration files generated (or if you don't have them just enable it) - it shows in a 'higher level' form of tables/mappings generated for you.

Problem is that you have 'one to one' relationship and your ProjectDocAccess to ProjectDoc is mapped with pk -> pk. Code first automatically does that for you in these cases as that's the only supported way of making the one to one.

So your ProjectDocAccessID is at all times mapped == the same as your ProjectDocID.

The ProjectDocID is auto-generated - but you need to put the access-id to match it yourself. (I'm guessing that could be automated but strictly in db terms it's not).

So, it can't auto-generate things. It has to be copied from the principal table, where the 'optional' is.

With your current entities it is what it is - but you could rearrange things maybe (though one-to-one are tough to make and could lead to issues if you don't get it right).

There is an option to create one to one using FK-s only (which would then allow you to place an 'independent' primary key on your 'access' table) - but requires manually injecting SQL CONSTRAINT - e.g. see this page - http://weblogs.asp.net/manavi/archive/2011/05/01/associations-in-ef-4-1-code-first-part-5-one-to-one-foreign-key-associations.aspx

OTHER TIPS

If you want the ProjectDocAccessID to be generated by the database (an Identity column) then you should decorate that property with the DatabaseGenerated attribute, like this:

[DatabaseGenerated(DatabaseGenerationOption.Identity)]
public int ProjectDocAccessID { get; set; }

As Andrei pointed out, you may also need to decorate it with the [Key] attribute as well.

Source: http://msdn.microsoft.com/en-US/data/jj591583

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top