In my generic base repository I have the following simple method for removing an entity from database:
public async Task<bool> DeleteAsync(TKey id)
{
var item = await Context.Set<TDb>().FindAsync(id).ConfigureAwait(false);
if (item == null)
return null;
var result = Context.Set<TDb>().Remove(item);
await Context.SaveChangesAsync().ConfigureAwait(false);
return result.State == EntityState.Modified || result.State == EntityState.Deleted;
}
Then in my DB Context I do set shadow properties in my save changes async in a following way (just like Microsoft suggests) (code simplified for better clarity):
public class EfCoreDbContext : DbContext, IUnitOfWork
{
public EfCoreDbContext(
DbContextOptions options
IConfiguration configuration) : base(options)
{
}
public override async Task<int> SaveChangesAsync(CancellationToken cancellationToken = default)
{
ChangeTracker.SetShadowISoftDeletableProperties();
ChangeTracker.SetShadowIUserOwnableProperties(UserResolver);
ChangeTracker.SetShadowIAuditableProperties(UserResolver);
return await base.SaveChangesAsync(cancellationToken).ConfigureAwait(false);
}
}
As visible from SaveChangesAsync method, I already use shadow properties for other tracking items, such as audits, or user ownership which works without a problem.
Finally, here is the Change Tracker code responsible for setting up soft delete
public static void SetShadowISoftDeletableProperties(this ChangeTracker changeTracker)
{
changeTracker.DetectChanges();
foreach (var entry in changeTracker.Entries())
{
if (typeof(ISoftDeletable).IsAssignableFrom(entry.Entity.GetType()))
{
if (entry.State == EntityState.Deleted)
{
entry.State = EntityState.Modified;
entry.Property("IsDeleted").CurrentValue = true;
}
else if (entry.State == EntityState.Added)
{
entry.Property("IsDeleted").CurrentValue = false;
}
else
{
entry.Property("IsDeleted").CurrentValue = entry.Property("IsDeleted").OriginalValue;
}
}
}
}
Everything works fine, IsDeleted property is being set successfully in the database; however when I inspect my result.State, it tells me that entity state is Unchanged (which causes that my DeleteAsync returns false), which I don't quite understand. Even in code it is visible, that I change state from Deleted to Modified.
I can surely ignore this and instead, return plain true after saving changes (in case of error, it would fail before); yet I am just trying to understand why I am getting this unexpected state result. Any help in respect to this matter would be highly appreciated.