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; }
}
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