Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

How to add a composite object? #4847

Closed
hypercodeplace opened this issue Mar 18, 2016 · 1 comment
Closed

How to add a composite object? #4847

hypercodeplace opened this issue Mar 18, 2016 · 1 comment

Comments

@hypercodeplace
Copy link

Hi!

I use EF Core.
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!

@smitpatel
Copy link
Contributor

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'.

As this exception says Insert statement failed because it violated the Foreign key constraint. There is a foreign key constraint on Parent table with ChildId as fk property which references Id property of Child table. Therefore ChildId must have value from existing values of Id in Child table.
Not long time ago, the behavior of Add was to add the entity and all dependent entities. Since Child is principal in this relationship, adding parent to dbcontext doesn't add child to context hence causing insert of parent with non-existent Child in db. Since this was confusing many people the behavior of Add has changed to include everything reachable. See #4424 for more details. With latest code, you wouldn't see this exception anymore.
The example in question 1 works because Parent is principal and GrandParent is dependent. Adding Parent will bring in GrandParent in context hence no exception.
Answer 2: With the version of EF core you are using you will probably require to add Child explicitly. If Child is not principal entity then use HasForeignKey while configuring relationship to specify which side the fk resides (making that side dependent).

P.S. [ForeignKey] annotation when used on a property contains the name of the navigation property for which it is FK and it appears on the dependent side only. In your model the ForeignKey annotations are specifying invalid navigations hence they are not used and should be removed.

@ajcvickers ajcvickers reopened this Oct 16, 2022
@ajcvickers ajcvickers closed this as not planned Won't fix, can't repro, duplicate, stale Oct 16, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants