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();
|
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. 返回执行结果
|
||||||
|
|||||||
@@ -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);
|
||||||
});
|
});
|
||||||
|
|||||||
Reference in New Issue
Block a user