With modern EFCore, you can do this very simply by Attaching the new Parent entity, which contains Children with IDs in them. It will reassign the FK of the child (or create it if no ID is specified), and create the new Person, all in one go
Ex:
var newOwner = new Person {
Cars = new List<Car> {
new Car { carId = theCarToMove.carId }
}
};
Context.Attach(newOwner);
await Context.SaveChangesAsync();
Beware that Attach can cause problems if your Context isn't truly transient, but as a bandaid you could always clear the ChangeTracker before attempting an Attach
EDIT: After trying this, I found that for some DB providers, it doesn't work directly. Instead, try:
foreach(var car in carsToMove)
{
Context.Attach(car);
car.Owner = newOwner;
}
Context.Attach(newOwner);
await Context.SaveChangesAsync();
Order matters when using Attach. The SQL query built by EFCore builds in reverse of the order you set it up in C#. If you attach the newOwner before the cars, the CREATE query is the last thing in the SQL, after the UPDATE for the cars. If this is the case, the cars can't UPDATE to the new OwnerId, because the newOwner did not have an ID at that point in the query. I believe this is also what's happening with the first code block, with some providers