Imagine I had the following code.
var myEntity = Context.MyEntities.GetById(id);
myEntity.SomeNavigationProperty = new MyNavigationProperty(...);
await Context.SaveChangesAsync();
I have the following mapping for MyEntity
builder.HasOne(o => o.SomeNavigationProperty).WithOne().HasForeignKey<MyEntity>(o => o.SomeNavigationPropertyId);
SaveChangesAsync fail with:
The database operation was expected to affect 1 row(s), but actually affected 0 row(s); data may have been modified or deleted since entities were loaded.
If I look at the change tracker after save, MyNavigationProperty has been marked as modified and not added.
Versions that work
var myEntity = new MyEntity(...);
myEntity.SomeNavigationProperty = new MyNavigationProperty(...);
await Context.AddAsync(myEntity);
await Context.SaveChangesAsync();
and
var myEntity = Context.MyEntities.GetById(id);
myEntity.SomeNavigationProperty = new MyNavigationProperty(...);
await Context.AddAsync(myEntity.SomeNavigationProperty);
await Context.SaveChangesAsync();
This behavior makes sense to a degree if I read up on https://docs.microsoft.com/en-us/dotnet/api/microsoft.entityframeworkcore.dbcontext.addasync?view=efcore-6.0. I do not completely understand why ef core decides to mark the untracked entity as modified instead of added though.
Either way... my problem is that my domain and repository are separated. In other words when the property gets set I do not have access to the context.
Is there a way I can tell the EF Core context to re-add all if its not already added without it complaining about duplicates?
Something like
await Context.RefreshAddAsync(myEntity);
where RefreshAddAsync will skip MyEntity (if it's already added) and mark MyNavigationProperty as added.
Any other suggestions appreciated. Worse case scenario I'll write a version of RefreshAddAsync using reflection, but would like a cleaner solution if there is one.