Search code examples
entity-frameworkforeign-keysaspnetboilerplatereferential-integritysoft-delete

How to check Foreign Key to restrict SoftDelete?


I would like to know if it is possible to check FK when using SoftDelete with ASP.NET Boilerplate.

Example

Suppose these tables:

Roles: RoleId (PK) - Description
Users: UserId (PK) - Name - RoleId (FK with Roles)

Data:

Roles
1 - admin
2 - guest
Users
1 - admin - 1
2 - john - 2

So RoleId 1 should not be deleted if it was already assigned to an existing User.

Thanks in advance.


Solution

  • Soft delete just sets a flag to mark the record as deleted.

    In ABP, you can write your own checks in ApplyAbpConceptsForDeletedEntity of your DbContext:

    public class AbpProjectNameDbContext // : ...
    {
        // ...
    
        protected override void ApplyAbpConceptsForDeletedEntity(EntityEntry entry, long? userId, EntityChangeReport changeReport)
        {
            CheckForeignKeys(entry);
    
            base.ApplyAbpConceptsForDeletedEntity(entry, userId, changeReport);
        }
    
        private void CheckForeignKeys(EntityEntry entry)
        {
            var entity = entry.Entity;
            if (!(entity is ISoftDelete))
            {
                // Foreign key constraints checked by database
                return;
            }
    
            var role = entity as Role;
            if (role != null)
            {
                if (Users.Any(u => u.Roles.Any(r => r.RoleId == role.Id)))
                {
                    throw new UserFriendlyException("Cannot delete assigned role!");
                }
            }
        }
    }
    

    Note that the template's RoleAppService actually removes users from the role before deleting it.