Entity Framework Core: How to add a composite object?

c# entity-framework entity-framework-core

Question

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!

1
3
3/18/2016 2:49:46 AM

Accepted Answer

This error is occurring only for the beta-8 version of EF. After I was updated EF to the rc1-final version error disappeared. It may be explained there is no graph tracking on the beta-8 version yet.

You can find more detailed information here.

2
3/21/2016 8:51:00 AM

Popular Answer

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


Related Questions





Related

Licensed under: CC-BY-SA with attribution
Not affiliated with Stack Overflow
Licensed under: CC-BY-SA with attribution
Not affiliated with Stack Overflow