How can I use EF to add multiple child entities to an object when the child has an identity key? How can I use EF to add multiple child entities to an object when the child has an identity key? sql-server sql-server

How can I use EF to add multiple child entities to an object when the child has an identity key?


I have run into the same identity "limitation" as well. It turns out that if you add a parent and any children, EF can handle the fact that the parent and children are all being added together. You run into problems when you Update the parent and insert two children at the same time. If you attach the parent, EF will automatically pick up those two children and attach them whether you want it to or not. Since we want it to auto generate the Id, we wouldn't set the primary key of the children. However, EF cannot handle items with the same Primary key when the parent is an Update and blows up since both have the same PK of 0 for both children.

The only way I have found around this is to manually set the ids of the children to different numbers. I usually set the first child's Id to -1, then -2 for the second child, and so on. This will cause EF to save the children and the key will automatically be updated due to the Identity running on the database because -1 and -2 are not valid identity values.

However, this will cause great pain if you have a 3rd level or beyond. Not only do you have to update this PK on each child, but then you'd have to update the FK on any of its children to this new -1 or -2 value. Otherwise, the save will fail again!

The only other option I see is really just to insert one child at a time and call save so the context isn't dealing with more than one object with the same PK, but that kind of defeats the purpose of an ORM...


Did you mentioned that you are adding a two times...?!

question.Answers.Add(a);question.Answers.Add(a);

Usually, to add items which their id is identity, you must skip setting the id. You also should add the [DatabaseGeneratedAttribute(DatabaseGeneratedOption.Identity)] attribute to these IDs:

public class Answer{    [DatabaseGeneratedAttribute(DatabaseGeneratedOption.Identity)]    public int AnswerId { get; set; }    public string Text { get; set; }    public int QuestionId { get; set; }    public virtual Question Question { get; set; }}

And add data like this:

var a = new Answer{    Text = "AAA",    QuestionId = 14};var b = new Answer{    Text = "BBB",    QuestionId = 14};dbContext.Answers.Add(a);dbContext.Answers.Add(b);dbContext.SaveChanges();// ...


Try these things:

  • use the Create() method of DbSet
  • add the new instances to the Answers collection of your Context

You have set the QuestionId appropriately for EF to realise the relationship. Also, do not explicitly set AnswerId to zero.

var a = new _uow.Answers.Create();a.Text = "AAA";a.QuestionId = 14;_uow.Answers.Add(a);var b = new _uow.Answers.Create();b.Text = "BBB";b.QuestionId = 14;_uow.Answers.Add(a);

You may need to make a call to _uow.ChangeTracker.DetectChanges() if you plan on querying the Answers collection of Question 14