В проекте, над которым я сейчас работаю, мне нужно проверить изменения во многих таблицах базы данных. Для этого я рассматриваю возможность работы с nuget Z.EntityFramework.Plus.Audit.EFCore . Я экспериментировал, и это, кажется, в основном соответствует моим потребностям. Я следил за документами здесь .
Можно сохранить записи аудита в моем контроллере следующим образом:
public myFunction(){
//...
var audit = new Audit();
_context.SaveChanges(audit);
}
Но если я сделаю это таким образом, это нарушит принцип СУХОЙ. Есть способ переопределить функции SaveChanges () и SaveChagesAsync (), и он творит чудеса. Такая вещь делается так:
public class ApplicationDbContext : IdentityDbContext<ApplicationUser>
{
public ApplicationDbContext(DbContextOptions<ApplicationDbContext> options) : base(options)
{
AuditManager.DefaultConfiguration.AutoSavePreAction = (context, audit) =>
// ADD "Where(x => x.AuditEntryID == 0)" to allow multiple SaveChanges with same Audit
(context as ApplicationDbContext).AuditEntries.AddRange(audit.Entries);
}
public override int SaveChanges()
{
var audit = new Audit { }; //Problem would be here
audit.PreSaveChanges(this);
var rowAffecteds = base.SaveChanges();
audit.PostSaveChanges();
if (audit.Configuration.AutoSavePreAction != null)
{
audit.Configuration.AutoSavePreAction(this, audit);
base.SaveChanges();
}
return rowAffecteds;
}
public override async Task<int> SaveChangesAsync(CancellationToken cancellationToken = default)
{
var audit = new Audit { }; //Problem would be here
audit.PreSaveChanges(this);
var rowAffecteds = await base.SaveChangesAsync(cancellationToken).ConfigureAwait(false);
audit.PostSaveChanges();
if (audit.Configuration.AutoSavePreAction != null)
{
audit.Configuration.AutoSavePreAction(this, audit);
await base.SaveChangesAsync(cancellationToken).ConfigureAwait(false);
}
return rowAffecteds;
}
//... DbContext Code
}
Теперь это лучший вариант, очень СУХОЙ и более экологичный. Проблема в том, как получить текущее имя пользователя, чтобы я мог сделать что-то вроде
var audit = new Audit { CreatedBy = "my_current_username"};
В контроллере вы можете использовать инструкцию
var username = this.User.Identity.Name;
но это не доступно в IdentityDbContext. Я попробовал ввести UserManager, но у него не было функции, которая могла бы работать.
ТЛ; др;
Как получить текущее имя пользователя в IdentityDbContext, когда я использую токены JWT?