58 lines
2.6 KiB
C#
58 lines
2.6 KiB
C#
using Microsoft.EntityFrameworkCore;
|
||
using TakeoutSaaS.Domain.Identity.Entities;
|
||
using TakeoutSaaS.Domain.Identity.Repositories;
|
||
|
||
namespace TakeoutSaaS.Infrastructure.Identity.Persistence;
|
||
|
||
/// <summary>
|
||
/// EF 角色-权限仓储。
|
||
/// </summary>
|
||
public sealed class EfRolePermissionRepository(IdentityDbContext dbContext) : IRolePermissionRepository
|
||
{
|
||
public Task<IReadOnlyList<RolePermission>> GetByRoleIdsAsync(long tenantId, IEnumerable<long> roleIds, CancellationToken cancellationToken = default)
|
||
=> dbContext.RolePermissions.AsNoTracking()
|
||
.Where(x => x.TenantId == tenantId && roleIds.Contains(x.RoleId))
|
||
.ToListAsync(cancellationToken)
|
||
.ContinueWith(t => (IReadOnlyList<RolePermission>)t.Result, cancellationToken);
|
||
|
||
public async Task AddRangeAsync(IEnumerable<RolePermission> rolePermissions, CancellationToken cancellationToken = default)
|
||
{
|
||
var toAdd = rolePermissions as RolePermission[] ?? rolePermissions.ToArray();
|
||
if (toAdd.Length == 0)
|
||
{
|
||
return;
|
||
}
|
||
|
||
await dbContext.RolePermissions.AddRangeAsync(toAdd, cancellationToken);
|
||
}
|
||
|
||
public async Task ReplaceRolePermissionsAsync(long tenantId, long roleId, IEnumerable<long> permissionIds, CancellationToken cancellationToken = default)
|
||
{
|
||
var strategy = dbContext.Database.CreateExecutionStrategy();
|
||
await strategy.ExecuteAsync(async () =>
|
||
{
|
||
await using var trx = await dbContext.Database.BeginTransactionAsync(cancellationToken);
|
||
|
||
// 1. 删除旧记录(原生 SQL,避免跟踪干扰)
|
||
await dbContext.Database.ExecuteSqlRawAsync(
|
||
"DELETE FROM \"role_permissions\" WHERE \"TenantId\" = {0} AND \"RoleId\" = {1};",
|
||
parameters: new object[] { tenantId, roleId },
|
||
cancellationToken: cancellationToken);
|
||
|
||
// 2. 插入新记录(防重复)
|
||
foreach (var permissionId in permissionIds.Distinct())
|
||
{
|
||
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);
|
||
});
|
||
}
|
||
|
||
public Task SaveChangesAsync(CancellationToken cancellationToken = default)
|
||
=> dbContext.SaveChangesAsync(cancellationToken);
|
||
}
|