public void ReassignLineItems(InvoiceUpdateDto invoiceUpdate)
{
Invoice invoiceInRepository = _unitOfWork.InvoiceRepository
.FirstOrDefault(invoice => invoice.Id == invoiceUpdate.Id);
invoiceInRepository.LineItems = invoiceUpdate.LineItems;
_unitOfWork.SaveChanges();
}
After retrieving Invoice
from the repository, and then detaching LineItem
from a navigation collection property by either removing it from the collection, or by assigning a new collection to Invoice
, Entity Framework tries to set the foreign key value to NULL. Instead, I want the foreign key to be intact, but the IsDeleted
property of LineItem
to change. I don't want to manually set the IsDeleted
property to false
, as that does not seem like a business logic responsibility.
In order to achieve this, I had to do the following.
public new void SaveChanges()
{
var entries = ChangeTracker.Entries()
.Where(e => e.State == EntityState.Added ||
e.State == EntityState.Modified ||
e.State == EntityState.Deleted);
foreach (var entry in entries)
{
if (entry.Entity is LineItem lineItem)
{
if (entry.State == EntityState.Modified
&& lineItem.Order == null)
{
lineItem.IsDeleted = true;
entry.Property(nameof(LineItem.Order)).IsModified = false;
}
}
}
base.SaveChanges()
}
Make a custom SaveChanges
method in the DbContext
class and have it find the detached LineItem
from the ChangeTracker
, and set the IsDeleted
to false IF the foreign key property was null, and have the change to the foreign key property be ignored. Finally, call base.SaveChanges
.
This works but it means that for each type that is removed from a navigation collection property, I have to write code inside the custom SaveChanges
method for that type. This could make the SaveChanges
method grow too large and cause performance issues because there would be a lot of if statements and type checks.
Is there a better way to achieve this?