ABP 扩展 UserOrganizationUnit / UserRole 等中间表
AbpUserOrganizationUnits / AbpUserRoles
这两张表是 ABP 框架内的表,因为 AbpUsers 用户主键现在是 long,新增了一个 Guid 类型的 PrimaryId 字段后,对外就不再传递 long 类型的主键,所以就出现了修改这两张中间表的需求。下面是扩展 UserRole 的实现过程,UserOrganizationUnit 实现过程一样。
1.新增 UserRoleExtend 类,并继承 Abp.Authorization.Users.UserRole,Discriminator 是必须的,值为扩展表的名称。
/// <summary>
/// 用户与角色中间表扩展
/// </summary>
public class UserRoleExtend : Abp.Authorization.Users.UserRole
{
/// <summary>
/// 用户 GUID 标识
/// </summary>
public Guid UserPrimaryId { get; set; }
/// <summary>
/// 自定义实体类名称(UserRoleExtend)
/// </summary>
[MaxLength(14)]
private string Discriminator { get { return "UserRoleExtend"; } }
}
2.在 DbContext 中定义 DbSet,这样才可以对外使用。
public virtual DbSet<UserRoleExtend> UserRoleExtend { get; set; }
3.创用户时同步更新中间表数据,这是重点。
/// <summary>
/// 创建用户成功后更新角色用户中间表扩展信息
/// </summary>
/// <param name="user"></param>
/// <returns></returns>
private async Task UpdateUserExtendInfo(User user)
{
var dbContext = _userRoleRepository.GetDbContext();
var sql = $"UPDATE \"AbpUserRoles\" SET Discriminator=@UserRoleExtend WHERE Discriminator!=@UserRoleExtend";
dbContext.Execute(sql, nameof(UserRoleExtend), nameof(UserRoleExtend));
sql = $"UPDATE \"AbpUserRoles\" SET UserPrimaryId=@PrimaryId WHERE UserId=@UserId AND UserPrimaryId IS NULL";
dbContext.Execute(sql, user.PrimaryId, user.Id);
}
第一句 SQL 是将 Discriminator 字段的值更新为 UserRoleExtend,这样 EntityFramework 才能查询出这条数据;
第二句 SQL 则是更新中间表中的扩展 UserPrimaryId 字段;
老实说,当前的实现方式很挫,这样就不能随意更换数据库或则需要对不同数据库进行SQL语句兼容处理,但在没找到更合适的方法前可以让功能正常运行起来。如果有更优雅的实现方式将在后面更新。