There is the following composite object, for example:
public class Parent
{
[Key]
public int Id { get; set; }
[ForeignKey("ChildRefId")]
public Guid ChildId { get; set; }
public Child Child { get; set; }
}
public class Child
{
[Key]
public Guid Id { get; set; }
[ForeignKey("ParentRefId")]
public int ParentId { get; set; }
public Parent Parent { get; set; }
}
Parent
and Child
has one-to-one relation:
modelBuilder.Entity<Parent>()
.HasOne(parent => parent.Child)
.WithOne(child => child.Parent)
.WillCascadeOnDelete();
I try to create new Parent
with Child
and save it in the DB:
var parent = new Parent { Child = new Child() };
dbContext.Parents.Add(parent);
dbContext.SaveChanges(); //<-- Exception!
...and get the following exception:
System.Data.SqlClient.SqlException: The INSERT statement conflicted with the FOREIGN KEY constraint "FK_Parent_Child_ChildId". The conflict occurred in database "MyDatabase", table "dbo.Child", column 'Id'.
If I use the db context to create a child it works fine:
var child = dbContext.Childs.Add(new Child());
var parent = new Parent { Child = child };
dbContext.Parents.Add(parent);
dbContext.SaveChanges(); //<-- It works fine
Question #1: I can easily add new entities to a nested collections without using context for create it. But it not works for one-to-one relation. For example:
var parent = new Parent();
parent.Grandparents.Add(new Grandparent();
dbContext.Parents.Add(parent);
dbContext.SaveChanges(); //<-- It works fine and parent with one new grandparent were created!
Why?
Question #2: Please, describe me what I do wrong and how I can save new parent with a child without context to create a child (like nested collections)?
Thank you!
You should remove the fluent syntax declaration (modelBuilder.Entity ...), it's not required in this instance.
You also need to use your context to create objects, and you should be specifying the Id key values. It's common to use Int's for keys- coupled with an automated database insert annotation that generates the keys for you. e.g.
public class Child {
[Key,DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public int Id { get; set; }
[ForeignKey("ParentRefId")]
public int ParentId { get; set; }
public Parent Parent { get; set; }
}
You should also use your context to create model objects something like:
using(MyDbContext db = new MyDbContext()) {
Child child = db.Childs.Create();
Parent parent = db.Parents.Create();
child.Parent = parent;
}
db.SaveChanges();
}