fix: de-dup role permission binding and use raw sql replace
This commit is contained in:
@@ -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. 返回执行结果
|
||||
|
||||
@@ -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);
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user