I implemented the Soft Deletes guide from JetBrains.
Summary:
- add DeletionStatus as a property on the database model
YourObject
- add global query filter in EntityFramework
YourObjectConfiguration
to always exclude deleted objects
builder.HasQueryFilter(el => el.DeletionStatus != DeletionStatus.Deleted)
- in requests where you need soft deleted data, use:
context.YourObjects.IgnoreQueryFilter().Include(..)
I use services and repositories, where the repositories make the db context calls.
The problem is, I end up having duplicate methods for any Get/Fetch. For some requests I need to ignore deleted data for others, I need all table records.
MyObjectRepository.cs
public Task<MyObject> GetByIdWithFilesAsync(int id)
{
return context.MyObjects
.Include(el => el.FileMyObjects)
.SingleOrDefaultAsync(el => el.Id == id);
}
public Task<MyObject> GetByIdWithFilesWithIgnoreFiltersAsync(int id)
{
return context.MyObjects
.IgnoreQueryFilters()
.Include(el => el.FileMyObjects)
.SingleOrDefaultAsync(el => el.Id == id);
}
Throughout the application there are many places where I need to duplicate repository methods and also add a long name suffix ‘WithIgnoreFilters’. I feel like I am doing something wrong and there must be some good practice.
Do you know a better a way to implement this? These are some options but I am not sure they are better
- optional parameter (i.e. Adding if check in every method)
- custom attribute