So I ran into this problem and I want to share the way I solved it, it is not as simple as calling saving changes twice, but it has some advantages over that method.
I had a situation where I wanted all the records to either succeed or fail, partial inserts of the children were not acceptable. I also didn't want to write code to delete the parent, if the child fails (what if there was a bug in that code, what if that code failed, etc.).
Secondly, it was possible to have a group of records, and I wanted all those records to succeed or fail in one transaction. Essentially, I got very specific with EF (my EF version is 6.1.3). Also I was only going one level deep in the parent child relationship, not an arbitrary number of levels deep.
int tempId = -1;
int parentTempId = -1;
foreach(var record in recordsToSave)
{
var childRecords = record.ChildRecords.ToList();
record.ChildRecords.Clear();
record.RecId = tempId;
parentTempId = tempId;
tempId--;
_db.Records.Add(record);
foreach(var childRecord in childRecords)
{
childRecord.RecId = tempId;
childRecord.ParentRecId = parentTempId;
tempId--;
_db.Records.Add(childRecord);
}
}
using (TransactionScope tran = new TransactionScope())
{
_db.SaveChanges();
tran.Complete();
}
- First I cleared the child collection and copied it over to a temporary list. EF was having problems with my relationship.
- I created a temporary id and assigned it to the parent record, and stored that for later use with the children.
- I manually connected the child to the parent - via my temp ids.
It worked and it also insert my data, in a visually appealing way (at least for me)