当我们在使用Abp框架的数据库实体类进行写入的时候,我们会继承来自框架提供的FullAuditedAggregateRoot类,这个类里面有提供CreationTime、CreatorId、LastModificationTime、LastModifierId、IsDeleted、DeleterId、DeletionTime这些与操作人相关的字段,当我们使用的是Abp框架的JWT Token授权的时候,这些字段会自动在我们操作数据库实体类的时候(比如:添加、删除、修改)自动记录下Token里的操作人信息。但是此时我们只有操作人的ID(CreatorId、DeleterId、LastModifierId)如果我们想把操作人的姓名也写到每个表里该怎么做呢?下面是解决方案
1.定义IHasExtendedAuditNames接口
定义IHasExtendedAuditNames接口,继承自IAuditedObject, IDeletionAuditedObject,定义CreatorName、LastModifierName、DeleterName字段,设置长度
public interface IHasExtendedAuditNames : IAuditedObject, IDeletionAuditedObject
{
[MaxLength(100)] // 统一设定长度为100
string CreatorName { get; set; }
[MaxLength(100)]
string LastModifierName { get; set; }
[MaxLength(100)]
string DeleterName { get; set; }
}
2.新建数据库实体基类
我们新增一个DbBaseColumn类,继承自IHasExtendedAuditNames接口,用作数据库实体的基类,给它实现定义CreatorName、LastModifierName、DeleterName,分别代表创建人用户名,编辑人用户名,删除人用户名,让所有数据库实体类继承于它,这样,我们在EntityFrameWork编译之后,每个数据库表都将新增这三个基础字段
public partial class DbBaseColumn<TKey> : FullAuditedAggregateRoot<TKey>, IHasExtendedAuditNames
{ /// <inheritdoc />
public virtual string? CreatorName { get; set; }
/// <inheritdoc />
public virtual string? LastModifierName { get; set; }
/// <inheritdoc />
public virtual string? DeleterName { get; set; }
protected DbBaseColumn()
{
}
protected DbBaseColumn(TKey id)
: base(id)
{
}
}
3.修改数据库实体类,统一继承自DbBaseColumn类
下面,我们要把各个数据库实体类修改继承,都继承自我们上文写的DbBaseColumn类,后续在去执行EF的升级数据库命令,这样数据库每个业务表字段都将新增CreatorName、LastModifierName、DeleterName这3个基础字段
public class ZPPF021 : DbBaseColumn<Guid>
{
protected ZPPF021(){
// only for ORM
}
/// <summary>
/// 号段类型
/// </summary>
public string CODE_TYPE { get; set; } = "";
internal ZPPF021(Guid id) : base(id)
{
//构造写这里不要写上面ZPPF021()方法
}
}
4.修改DbContext,重写SaveChangesAsync
最后,我们要在数据库对应的DbContext,打开DbContext类,新增重写SaveChangesAsync方法,在每次操作提交的时候,把我们JWT Token的操作人信息取下来,保存到库表
public override async Task<int> SaveChangesAsync(bool acceptAllChangesOnSuccess, CancellationToken cancellationToken = default)
{
foreach (var entry in ChangeTracker.Entries<IHasExtendedAuditNames>())
{
if (entry.State == EntityState.Added)
{
if (_currentUserManager != null)
{
entry.Entity.CreatorName = _currentUserManager.UserName;
entry.Entity.LastModifierName = _currentUserManager.UserName;
}
}
else if (entry.State == EntityState.Modified)
{
if (_currentUserManager != null)
{
entry.Entity.LastModifierName = _currentUserManager.UserName;
}
}
else if (entry.State == EntityState.Deleted)
{
if (_currentUserManager != null)
{
entry.Entity.DeleterName = _currentUserManager.UserName;
}
}
}
return await base.SaveChangesAsync(acceptAllChangesOnSuccess, cancellationToken);
}
_currentUserManager需要我们在DbContext构造的时候引入,方法如下
private readonly ICurrentUser _currentUserManager; // 注入 ICurrentUser
public NumBdDbContext(
DbContextOptions<NumBdDbContext> options,
ICurrentUser currentUserManager // 通过构造函数注入
) : base(options)
{
_currentUserManager= currentUserManager;
}
这样,我们就可以在Abp修改数据库操作时,同时写下操作人用户名