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(); var tenantId = request.TenantId ?? tenantProvider.GetCurrentTenantId();
// 2. 覆盖式绑定权限 // 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); await rolePermissionRepository.SaveChangesAsync(cancellationToken);
// 3. 返回执行结果 // 3. 返回执行结果

View File

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