Как проверить удаление ролей? - PullRequest
0 голосов
/ 15 апреля 2020

Когда роль удалена у пользователя, мне нужно отследить, кто это сделал (ie. Который AbpUser) и когда они это сделали.

Очевидное решение состоит в том, чтобы переопределить сущность UserRole так, чтобы он наследуется от FullAuditedEntity вместо CreationAuditedEntity, но сущность UserRole определена в пакете nuget, поэтому я не могу просто изменить определение.

Есть ли способ добиться такого поведения, которого я не вижу?

Вот то, что я пробовал до сих пор.

Подход 1. Я попытался обработать это на уровне базы данных, установив триггер удаления в таблице AbpUserRole, который вставлял бы запись в таблицу AbpUserRoleDeleted, но я не могу придумать способ узнать, какой AbpUser сделал удаление с помощью этого подхода. Я могу только отслеживать, когда произошло действие.

Подход 2: Я попытался прослушать событие домена EntityDeleted на объектах UserRole, но, похоже, оно не срабатывает. Интересно, что событие EntityUpdated срабатывает, когда я удаляю роль у пользователя, но даже если предположить, что это событие будет срабатывать только при удалении пользовательской роли, в данных события все равно не указано, кто произвел удаление. Если бы это произошло, я мог бы вручную сохранить информацию аудита в отдельной таблице, как триггер удаления базы данных, но на этот раз у меня был бы AbpUser, который отвечал за удаление.

Подход 3: Я попытался расширить объект UserRole, выполнив шаги здесь . Мне удалось реализовать интерфейс IDeletionAudited и сгенерировать миграцию, которая создает связанные столбцы в таблице AbpUserRoles, но удаление роли у пользователя выполняет полное удаление вместо мягкого удаления, поэтому я не могу сказать, заполнены ли даже столбцы , Я предполагаю, что они этого не делают.

Подход 4: Я пытался включить историю сущностей для сущности UserRole, но, похоже, она отслеживает только то, когда создается сущность UserRole.

1 Ответ

0 голосов
/ 20 апреля 2020

Это, кажется, работает нормально.

//src\aspnet-core\src\Company.App.EntityFrameworkCore\EntityFrameworkCore\AppDbContext.cs
namespace Company.App.EntityFrameworkCore
{
    public class AppDbContext : AbpZeroDbContext<Tenant, Role, User, AppDbContext>, IAbpPersistedGrantDbContext
    {
        public AppDbContext(DbContextOptions<AppDbContext> options) : base(options)
        {
            ChangeTracker.StateChanged += OnEntityStateChanged;
        }

        private void OnEntityStateChanged(object sender, EntityStateChangedEventArgs e)
        {
            if (e.Entry.Entity is UserRole && e.NewState == EntityState.Deleted)
            {
                //update instead of delete
                e.Entry.State = EntityState.Modified;
                e.Entry.CurrentValues["IsDeleted"] = true;
                e.Entry.CurrentValues["DeletionTime"] = DateTime.Now;
                e.Entry.CurrentValues["DeleterUserId"] = AbpSession.UserId;
            }
        }

        protected override void OnModelCreating(ModelBuilder modelBuilder)
        {
            //use query filter on the `IsDeleted` shadow property
            modelBuilder.Entity<UserRole>().HasQueryFilter(p => !EF.Property<bool>(p, "IsDeleted"));
            modelBuilder.Entity<UserRole>().Property<bool>("IsDeleted");
            modelBuilder.Entity<UserRole>().Property<DateTime?>("DeletionTime").IsRequired(false);
            modelBuilder.Entity<UserRole>().Property<long?>("DeleterUserId").IsRequired(false);
        }
    }
}

...