Is there a better way to soft delete navigation properties in Entity Framework 6 when using Repository pattern?

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?

Apr 20, 2025 - 17:03
 0
Is there a better way to soft delete navigation properties in Entity Framework 6 when using Repository pattern?
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?