Когда роль удаляется у пользователя, мне нужно отслеживать, кто это сделал (например, какой AbpUser) и когда они это сделали.
Очевидным решением является переопределение сущности UserRole так, чтобы она унаследовала от FullAuditedEntity вместо CreationAuditedEntity, но сущность UserRole определена в пакете nuget, поэтому я не могу просто изменить определение.
Есть ли способ добиться такого поведения, которого я не вижу?
Вот что я пытался до сих пор.
Подход 1: я попытался справиться с этим на уровне базы данных, установив триггер удаления в таблице AbpUserRole, который будет вставлять запись в таблицу AbpUserRoleDeleted, но я не могу придумать способ узнать, какой AbpUser сделал удаление с помощью этого подход. Я могу только отследить, когда произошло действие.
Подход 2: я попытался прослушать событие домена EntityDeleted на объектах UserRole, но, похоже, оно не срабатывает. Интересно, что событие EntityUpdated запускается, когда я удаляю роль у пользователя, но даже если предположить, что это событие будет запускаться только при удалении UserRole, данные события по-прежнему не включают того, кто сделал удаление. Если бы это было так, я мог бы вручную сохранить информацию аудита в отдельной таблице, как это сделал бы триггер удаления базы данных, но на этот раз у меня был бы AbpUser, который отвечал за удаление.
Подход 3. Я попытался расширить сущность UserRole, выполнив следующие действия: здесь. Мне удалось реализовать интерфейс IDeletionAudited и сгенерировать миграцию, которая создает связанные столбцы в таблице AbpUserRoles, но удаление роли от пользователя выполняет жесткое удаление вместо мягкого удаления, поэтому я не могу сказать, заполняются ли столбцы . Я предполагаю, что нет.
Подход 4: я попытался включить историю сущностей для сущности UserRole, но, похоже, она отслеживает только то, когда создается сущность UserRole.
1 ответ
Кажется, это нормально работает.
//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);
}
}
}
Похожие вопросы
Новые вопросы
c#
C # (произносится как «резкий») - это высокоуровневый, статически типизированный язык программирования с несколькими парадигмами, разработанный Microsoft. Код C # обычно нацелен на семейство инструментов и сред выполнения Microsoft .NET, включая, среди прочего, .NET Framework, .NET Core и Xamarin. Используйте этот тег для вопросов о коде, написанном на C # или в формальной спецификации C #.