fix: de-dup role permission binding and use raw sql replace

This commit is contained in:
2025-12-06 22:52:02 +08:00
parent 33a3b349c4
commit cf9927c078
2 changed files with 18 additions and 15 deletions

View File

@@ -19,7 +19,12 @@ public sealed class BindRolePermissionsCommandHandler(
var tenantId = request.TenantId ?? tenantProvider.GetCurrentTenantId();
// 2. 覆盖式绑定权限
await rolePermissionRepository.ReplaceRolePermissionsAsync(tenantId, request.RoleId, request.PermissionIds, cancellationToken);
var distinctPermissionIds = request.PermissionIds
.Where(id => id > 0)
.Distinct()
.ToArray();
await rolePermissionRepository.ReplaceRolePermissionsAsync(tenantId, request.RoleId, distinctPermissionIds, cancellationToken);
await rolePermissionRepository.SaveChangesAsync(cancellationToken);
// 3. 返回执行结果

View File

@@ -33,22 +33,20 @@ public sealed class EfRolePermissionRepository(IdentityDbContext dbContext) : IR
{
await using var trx = await dbContext.Database.BeginTransactionAsync(cancellationToken);
var existing = await dbContext.RolePermissions
.Where(x => x.TenantId == tenantId && x.RoleId == roleId)
.ToListAsync(cancellationToken);
// 1. 删除旧记录(原生 SQL避免跟踪干扰
await dbContext.Database.ExecuteSqlRawAsync(
"DELETE FROM \"role_permissions\" WHERE \"TenantId\" = {0} AND \"RoleId\" = {1};",
parameters: new object[] { tenantId, roleId },
cancellationToken: cancellationToken);
dbContext.RolePermissions.RemoveRange(existing);
await dbContext.SaveChangesAsync(cancellationToken);
var toAdd = permissionIds.Distinct().Select(permissionId => new RolePermission
// 2. 插入新记录(防重复)
foreach (var permissionId in permissionIds.Distinct())
{
TenantId = tenantId,
RoleId = roleId,
PermissionId = permissionId
});
await dbContext.RolePermissions.AddRangeAsync(toAdd, cancellationToken);
await dbContext.SaveChangesAsync(cancellationToken);
await dbContext.Database.ExecuteSqlRawAsync(
"INSERT INTO \"role_permissions\" (\"TenantId\",\"RoleId\",\"PermissionId\",\"CreatedAt\",\"CreatedBy\",\"UpdatedAt\",\"UpdatedBy\",\"DeletedAt\",\"DeletedBy\") VALUES ({0},{1},{2},NOW(),NULL,NULL,NULL,NULL,NULL) ON CONFLICT DO NOTHING;",
parameters: new object[] { tenantId, roleId, permissionId },
cancellationToken: cancellationToken);
}
await trx.CommitAsync(cancellationToken);
});