fix: wrap identity permission bindings with execution strategy transactions
This commit is contained in:
@@ -86,35 +86,42 @@ public sealed class EfRoleTemplateRepository(IdentityDbContext dbContext) : IRol
|
||||
|
||||
private async Task ReplacePermissionsInternalAsync(RoleTemplate template, IEnumerable<string> permissionCodes, CancellationToken cancellationToken)
|
||||
{
|
||||
await using var trx = await dbContext.Database.BeginTransactionAsync(cancellationToken);
|
||||
|
||||
// 确保模板已持久化,便于 FK 正确填充
|
||||
if (!dbContext.Entry(template).IsKeySet || template.Id == 0)
|
||||
var strategy = dbContext.Database.CreateExecutionStrategy();
|
||||
await strategy.ExecuteAsync(async () =>
|
||||
{
|
||||
await using var trx = await dbContext.Database.BeginTransactionAsync(cancellationToken);
|
||||
|
||||
// 1. 确保模板已持久化,便于 FK 正确填充
|
||||
if (!dbContext.Entry(template).IsKeySet || template.Id == 0)
|
||||
{
|
||||
await dbContext.SaveChangesAsync(cancellationToken);
|
||||
}
|
||||
|
||||
// 2. 归一化权限编码
|
||||
var normalized = permissionCodes
|
||||
.Where(code => !string.IsNullOrWhiteSpace(code))
|
||||
.Select(code => code.Trim())
|
||||
.Distinct(StringComparer.OrdinalIgnoreCase)
|
||||
.ToArray();
|
||||
|
||||
// 3. 清空旧权限
|
||||
var existing = await dbContext.RoleTemplatePermissions
|
||||
.Where(x => x.RoleTemplateId == template.Id)
|
||||
.ToListAsync(cancellationToken);
|
||||
dbContext.RoleTemplatePermissions.RemoveRange(existing);
|
||||
await dbContext.SaveChangesAsync(cancellationToken);
|
||||
}
|
||||
|
||||
var normalized = permissionCodes
|
||||
.Where(code => !string.IsNullOrWhiteSpace(code))
|
||||
.Select(code => code.Trim())
|
||||
.Distinct(StringComparer.OrdinalIgnoreCase)
|
||||
.ToArray();
|
||||
// 4. 插入新权限
|
||||
var toAdd = normalized.Select(code => new RoleTemplatePermission
|
||||
{
|
||||
RoleTemplateId = template.Id,
|
||||
PermissionCode = code
|
||||
});
|
||||
|
||||
var existing = await dbContext.RoleTemplatePermissions
|
||||
.Where(x => x.RoleTemplateId == template.Id)
|
||||
.ToListAsync(cancellationToken);
|
||||
await dbContext.RoleTemplatePermissions.AddRangeAsync(toAdd, cancellationToken);
|
||||
await dbContext.SaveChangesAsync(cancellationToken);
|
||||
|
||||
dbContext.RoleTemplatePermissions.RemoveRange(existing);
|
||||
await dbContext.SaveChangesAsync(cancellationToken);
|
||||
|
||||
var toAdd = normalized.Select(code => new RoleTemplatePermission
|
||||
{
|
||||
RoleTemplateId = template.Id,
|
||||
PermissionCode = code
|
||||
await trx.CommitAsync(cancellationToken);
|
||||
});
|
||||
|
||||
await dbContext.RoleTemplatePermissions.AddRangeAsync(toAdd, cancellationToken);
|
||||
await dbContext.SaveChangesAsync(cancellationToken);
|
||||
await trx.CommitAsync(cancellationToken);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user