forked from ddrilling/AsbCloudServer
Use cacheTable for roles and permissions
This commit is contained in:
parent
00dd39b587
commit
539905e8e0
@ -8,13 +8,12 @@ namespace AsbCloudApp.Services
|
|||||||
where Tdto : Data.IId
|
where Tdto : Data.IId
|
||||||
{
|
{
|
||||||
List<string> Incledes { get; }
|
List<string> Incledes { get; }
|
||||||
Task<int> DeleteAsync(int id, CancellationToken token = default);
|
|
||||||
Task<int> DeleteAsync(IEnumerable<int> ids, CancellationToken token = default);
|
|
||||||
Task<IEnumerable<Tdto>> GetAllAsync(CancellationToken token = default);
|
|
||||||
Task<Tdto> GetAsync(int id, CancellationToken token = default);
|
|
||||||
Task<Data.PaginationContainer<Tdto>> GetPageAsync(int skip = 0, int take = 32, CancellationToken token = default);
|
|
||||||
Task<int> InsertAsync(Tdto newItem, CancellationToken token = default);
|
Task<int> InsertAsync(Tdto newItem, CancellationToken token = default);
|
||||||
Task<int> InsertRangeAsync(IEnumerable<Tdto> newItems, CancellationToken token = default);
|
Task<int> InsertRangeAsync(IEnumerable<Tdto> newItems, CancellationToken token = default);
|
||||||
|
Task<IEnumerable<Tdto>> GetAllAsync(CancellationToken token = default);
|
||||||
|
Task<Tdto> GetAsync(int id, CancellationToken token = default);
|
||||||
Task<int> UpdateAsync(int id, Tdto item, CancellationToken token = default);
|
Task<int> UpdateAsync(int id, Tdto item, CancellationToken token = default);
|
||||||
|
Task<int> DeleteAsync(int id, CancellationToken token = default);
|
||||||
|
Task<int> DeleteAsync(IEnumerable<int> ids, CancellationToken token = default);
|
||||||
}
|
}
|
||||||
}
|
}
|
10
AsbCloudApp/Services/IPaginationService.cs
Normal file
10
AsbCloudApp/Services/IPaginationService.cs
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
using System.Threading;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
namespace AsbCloudApp.Services
|
||||||
|
{
|
||||||
|
public interface IPaginationService<Tdto>
|
||||||
|
{
|
||||||
|
Task<Data.PaginationContainer<Tdto>> GetPageAsync(int skip = 0, int take = 32, CancellationToken token = default);
|
||||||
|
}
|
||||||
|
}
|
@ -11,6 +11,6 @@ namespace AsbCloudApp.Services
|
|||||||
Task<int> InsertRangeAsync(IEnumerable<PermissionDto> dtos, CancellationToken token);
|
Task<int> InsertRangeAsync(IEnumerable<PermissionDto> dtos, CancellationToken token);
|
||||||
Task<int> UpdateAsync(PermissionDto dto, CancellationToken token);
|
Task<int> UpdateAsync(PermissionDto dto, CancellationToken token);
|
||||||
Task<int> DeleteAsync(int idUserRole, int idPermission, CancellationToken token);
|
Task<int> DeleteAsync(int idUserRole, int idPermission, CancellationToken token);
|
||||||
|
Task<int> DeleteAllByRoleAsync(int idUserRole, CancellationToken token);
|
||||||
}
|
}
|
||||||
}
|
}
|
8
AsbCloudApp/Services/IUserRoleService.cs
Normal file
8
AsbCloudApp/Services/IUserRoleService.cs
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
using AsbCloudApp.Data;
|
||||||
|
|
||||||
|
namespace AsbCloudApp.Services
|
||||||
|
{
|
||||||
|
public interface IUserRoleService: ICrudService<UserRoleDto>
|
||||||
|
{
|
||||||
|
}
|
||||||
|
}
|
@ -1,8 +1,5 @@
|
|||||||
using AsbCloudApp.Data;
|
using AsbCloudApp.Data;
|
||||||
using System;
|
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
|
||||||
using System.Text;
|
|
||||||
using System.Threading;
|
using System.Threading;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
@ -42,41 +42,35 @@ namespace AsbCloudInfrastructure
|
|||||||
services.AddTransient<IAuthService, AuthService>();
|
services.AddTransient<IAuthService, AuthService>();
|
||||||
services.AddTransient<IClusterService, ClusterService>();
|
services.AddTransient<IClusterService, ClusterService>();
|
||||||
services.AddTransient<IDrillFlowChartService, DrillFlowChartService>();
|
services.AddTransient<IDrillFlowChartService, DrillFlowChartService>();
|
||||||
services.AddTransient<IDrillParamsService, DrillParamsService>();
|
|
||||||
services.AddTransient<IDrillingProgramService, DrillingProgramService>();
|
services.AddTransient<IDrillingProgramService, DrillingProgramService>();
|
||||||
|
services.AddTransient<IDrillParamsService, DrillParamsService>();
|
||||||
services.AddTransient<IEventService, EventService>();
|
services.AddTransient<IEventService, EventService>();
|
||||||
services.AddTransient<IFileService, FileService>();
|
services.AddTransient<IFileService, FileService>();
|
||||||
services.AddTransient<IMeasureService, MeasureService>();
|
services.AddTransient<IMeasureService, MeasureService>();
|
||||||
services.AddTransient<IMessageService, MessageService>();
|
services.AddTransient<IMessageService, MessageService>();
|
||||||
|
services.AddTransient<IOperationsStatService, OperationsStatService>();
|
||||||
services.AddTransient<IPermissionService, PermissionService>();
|
services.AddTransient<IPermissionService, PermissionService>();
|
||||||
services.AddTransient<IReportService, ReportService>();
|
services.AddTransient<IReportService, ReportService>();
|
||||||
|
services.AddTransient<ISetpointsService, SetpointsService>();
|
||||||
services.AddTransient<ITelemetryAnalyticsService, TelemetryAnalyticsService>();
|
services.AddTransient<ITelemetryAnalyticsService, TelemetryAnalyticsService>();
|
||||||
services.AddTransient<ITelemetryService, TelemetryService>();
|
services.AddTransient<ITelemetryService, TelemetryService>();
|
||||||
services.AddTransient<ITelemetryUserService, TelemetryUserService>();
|
services.AddTransient<ITelemetryUserService, TelemetryUserService>();
|
||||||
services.AddTransient<ITimeZoneService, TimeZoneService>();
|
services.AddTransient<ITimeZoneService, TimeZoneService>();
|
||||||
|
services.AddTransient<IUserRoleService, UserRoleService>();
|
||||||
|
services.AddTransient<IWellService, WellService>();
|
||||||
services.AddTransient<IWellCompositeService, WellCompositeService>();
|
services.AddTransient<IWellCompositeService, WellCompositeService>();
|
||||||
services.AddTransient<IWellOperationImportService, WellOperationImportService>();
|
services.AddTransient<IWellOperationImportService, WellOperationImportService>();
|
||||||
services.AddTransient<IWellOperationService, WellOperationService>();
|
services.AddTransient<IWellOperationService, WellOperationService>();
|
||||||
services.AddTransient<IOperationsStatService, OperationsStatService>();
|
|
||||||
services.AddTransient<IWellOperationImportService, WellOperationImportService>();
|
|
||||||
services.AddTransient<IWellCompositeService, WellCompositeService>();
|
|
||||||
services.AddTransient<IMeasureService, MeasureService>();
|
|
||||||
services.AddTransient<IDrillingProgramService, DrillingProgramService>();
|
|
||||||
services.AddTransient<IDrillParamsService, DrillParamsService>();
|
|
||||||
services.AddTransient<IDrillFlowChartService, DrillFlowChartService>();
|
|
||||||
services.AddTransient<ITimeZoneService, TimeZoneService>();
|
|
||||||
services.AddTransient<ISetpointsService, SetpointsService>();
|
|
||||||
|
|
||||||
// admin crud services:
|
// admin crud services:
|
||||||
services.AddTransient<ICrudService<ClusterDto>, CrudServiceBase<ClusterDto, Cluster>>();
|
|
||||||
services.AddTransient<ICrudService<CompanyDto>, CrudServiceBase<CompanyDto, Company>>();
|
|
||||||
services.AddTransient<ICrudService<DepositDto>, CrudServiceBase<DepositDto, Deposit>>();
|
|
||||||
services.AddTransient<ICrudService<DrillParamsDto>, DrillParamsService>();
|
|
||||||
services.AddTransient<ICrudService<PermissionInfoDto>, CrudServiceBase<PermissionInfoDto, PermissionInfo>>();
|
|
||||||
services.AddTransient<ICrudService<TelemetryDto>, CrudServiceBase<TelemetryDto, Telemetry>>();
|
|
||||||
services.AddTransient<ICrudService<UserDto>, CrudServiceBase<UserDto, User>>();
|
|
||||||
services.AddTransient<ICrudService<UserRoleDto>, UserRoleService>();
|
|
||||||
services.AddTransient<ICrudService<WellDto>, CrudServiceBase<WellDto, Well>>();
|
services.AddTransient<ICrudService<WellDto>, CrudServiceBase<WellDto, Well>>();
|
||||||
|
services.AddTransient<ICrudService<UserDto>, CrudServiceBase<UserDto, User>>();
|
||||||
|
services.AddTransient<ICrudService<TelemetryDto>, CrudServiceBase<TelemetryDto, Telemetry>>();
|
||||||
|
services.AddTransient<ICrudService<PermissionInfoDto>, CrudServiceBase<PermissionInfoDto, PermissionInfo>>();
|
||||||
|
services.AddTransient<ICrudService<DrillParamsDto>, DrillParamsService>();
|
||||||
|
services.AddTransient<ICrudService<DepositDto>, CrudServiceBase<DepositDto, Deposit>>();
|
||||||
|
services.AddTransient<ICrudService<CompanyDto>, CrudServiceBase<CompanyDto, Company>>();
|
||||||
|
services.AddTransient<ICrudService<ClusterDto>, CrudServiceBase<ClusterDto, Cluster>>();
|
||||||
|
|
||||||
// TelemetryData services
|
// TelemetryData services
|
||||||
services.AddTransient<ITelemetryDataService<TelemetryDataSaubDto>, TelemetryDataSaubService>();
|
services.AddTransient<ITelemetryDataService<TelemetryDataSaubDto>, TelemetryDataSaubService>();
|
||||||
|
@ -65,15 +65,17 @@ namespace AsbCloudInfrastructure.Services.Cache
|
|||||||
/// It may be needed to avoid multiple operations like Refresh().
|
/// It may be needed to avoid multiple operations like Refresh().
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="action">(wasFree) => {...}</param>
|
/// <param name="action">(wasFree) => {...}</param>
|
||||||
/// <returns>false - semaphore.Wait returned by timeout</returns>
|
/// <returns>default if semaphoreTimeout. Or result of func(..)</returns>
|
||||||
private static bool Sync(Action<bool> action)
|
private static T Sync<T>(Func<bool, T> func)
|
||||||
{
|
{
|
||||||
var wasFree = semaphore.CurrentCount > 0;
|
var wasFree = semaphore.CurrentCount > 0;
|
||||||
if (!semaphore.Wait(semaphoreTimeout))
|
T result = default;
|
||||||
return false;
|
if (func is null || !semaphore.Wait(semaphoreTimeout))
|
||||||
|
return result;
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
action?.Invoke(wasFree);
|
result = func.Invoke(wasFree);
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
@ -85,7 +87,7 @@ namespace AsbCloudInfrastructure.Services.Cache
|
|||||||
{
|
{
|
||||||
semaphore.Release();
|
semaphore.Release();
|
||||||
}
|
}
|
||||||
return true;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@ -94,15 +96,18 @@ namespace AsbCloudInfrastructure.Services.Cache
|
|||||||
/// It may be needed to avoid multiple operations like Refresh().
|
/// It may be needed to avoid multiple operations like Refresh().
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="action">(wasFree) => {...}</param>
|
/// <param name="action">(wasFree) => {...}</param>
|
||||||
/// <returns>false - semaphore.Wait returned by timeout</returns>
|
/// <returns>default if semaphoreTimeout. Or result of func(..)</returns>
|
||||||
private static async Task<bool> SyncAsync(Func<bool, CancellationToken, Task> task, CancellationToken token = default)
|
private static async Task<T> SyncAsync<T>(Func<bool, CancellationToken, Task<T>> funcAsync, CancellationToken token = default)
|
||||||
{
|
{
|
||||||
var wasFree = semaphore.CurrentCount > 0;
|
var wasFree = semaphore.CurrentCount > 0;
|
||||||
if (!await semaphore.WaitAsync(semaphoreTimeout, token).ConfigureAwait(false))
|
T result = default;
|
||||||
return false;
|
|
||||||
|
if (funcAsync is null || !await semaphore.WaitAsync(semaphoreTimeout, token).ConfigureAwait(false))
|
||||||
|
return result;
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
await task?.Invoke(wasFree, token);
|
result = await funcAsync.Invoke(wasFree, token);
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
@ -114,10 +119,10 @@ namespace AsbCloudInfrastructure.Services.Cache
|
|||||||
{
|
{
|
||||||
semaphore.Release();
|
semaphore.Release();
|
||||||
}
|
}
|
||||||
return true;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void InternalRefresh(bool force)
|
private int InternalRefresh(bool force)
|
||||||
{
|
{
|
||||||
if (force || data.LastResreshDate + minPeriodRefresh < DateTime.Now)
|
if (force || data.LastResreshDate + minPeriodRefresh < DateTime.Now)
|
||||||
{
|
{
|
||||||
@ -128,9 +133,10 @@ namespace AsbCloudInfrastructure.Services.Cache
|
|||||||
cached.AddRange(entities);
|
cached.AddRange(entities);
|
||||||
data.LastResreshDate = DateTime.Now;
|
data.LastResreshDate = DateTime.Now;
|
||||||
}
|
}
|
||||||
|
return cached.Count;
|
||||||
}
|
}
|
||||||
|
|
||||||
private async Task InternalRefreshAsync(bool force, CancellationToken token = default)
|
private async Task<int> InternalRefreshAsync(bool force, CancellationToken token = default)
|
||||||
{
|
{
|
||||||
if (force || data.LastResreshDate + minPeriodRefresh < DateTime.Now)
|
if (force || data.LastResreshDate + minPeriodRefresh < DateTime.Now)
|
||||||
{
|
{
|
||||||
@ -142,24 +148,18 @@ namespace AsbCloudInfrastructure.Services.Cache
|
|||||||
cached.AddRange(entities);
|
cached.AddRange(entities);
|
||||||
data.LastResreshDate = DateTime.Now;
|
data.LastResreshDate = DateTime.Now;
|
||||||
}
|
}
|
||||||
|
return cached.Count;
|
||||||
}
|
}
|
||||||
|
|
||||||
public int Refresh(bool force)
|
public int Refresh(bool force)
|
||||||
{
|
=> Sync((wasFree) => wasFree ? InternalRefresh(force) : 0);
|
||||||
Sync((wasFree) => {
|
|
||||||
if (wasFree)
|
|
||||||
InternalRefresh(force);
|
|
||||||
});
|
|
||||||
return cached.Count;
|
|
||||||
}
|
|
||||||
|
|
||||||
public async Task<int> RefreshAsync(bool force, CancellationToken token = default)
|
public Task<int> RefreshAsync(bool force, CancellationToken token = default)
|
||||||
{
|
{
|
||||||
await SyncAsync(async (wasFree, token) => {
|
return SyncAsync(async (wasFree, token) =>
|
||||||
if (wasFree)
|
{
|
||||||
await InternalRefreshAsync(force, token).ConfigureAwait(false);
|
return wasFree ? await InternalRefreshAsync(force, token).ConfigureAwait(false) : 0;
|
||||||
}, token).ConfigureAwait(false);
|
}, token);
|
||||||
return cached.Count;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public bool Contains(Func<TEntity, bool> predicate)
|
public bool Contains(Func<TEntity, bool> predicate)
|
||||||
@ -169,25 +169,22 @@ namespace AsbCloudInfrastructure.Services.Cache
|
|||||||
=> await FirstOrDefaultAsync(predicate, token) != default;
|
=> await FirstOrDefaultAsync(predicate, token) != default;
|
||||||
|
|
||||||
public TEntity GetOrCreate(Func<TEntity, bool> predicate, Func<TEntity> makeNew)
|
public TEntity GetOrCreate(Func<TEntity, bool> predicate, Func<TEntity> makeNew)
|
||||||
|
=> Sync(wasFree =>
|
||||||
{
|
{
|
||||||
TEntity result = default;
|
var result = cached.FirstOrDefault(predicate);
|
||||||
Sync(wasFree => {
|
|
||||||
result = cached.FirstOrDefault(predicate);
|
|
||||||
if (result != default)
|
if (result != default)
|
||||||
return;
|
return result;
|
||||||
|
|
||||||
InternalRefresh(true);
|
InternalRefresh(true);
|
||||||
result = cached.FirstOrDefault(predicate);
|
result = cached.FirstOrDefault(predicate);
|
||||||
if (result != default)
|
if (result != default)
|
||||||
return;
|
return result;
|
||||||
|
|
||||||
var entry = dbSet.Add(makeNew());
|
var entry = dbSet.Add(makeNew());
|
||||||
context.SaveChanges();
|
context.SaveChanges();
|
||||||
InternalRefresh(true);
|
InternalRefresh(true);
|
||||||
result = entry.Entity;
|
return entry.Entity;
|
||||||
});
|
});
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
public TEntity FirstOrDefault()
|
public TEntity FirstOrDefault()
|
||||||
{
|
{
|
||||||
@ -263,11 +260,11 @@ namespace AsbCloudInfrastructure.Services.Cache
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Upsert(TEntity entity)
|
public int Upsert(TEntity entity)
|
||||||
{
|
{
|
||||||
if (entity == default)
|
if (entity == default)
|
||||||
return;
|
return 0;
|
||||||
Sync((wasFree) =>
|
return Sync((wasFree) =>
|
||||||
{
|
{
|
||||||
if (dbSet.Contains(entity))
|
if (dbSet.Contains(entity))
|
||||||
dbSet.Update(entity);
|
dbSet.Update(entity);
|
||||||
@ -276,26 +273,29 @@ namespace AsbCloudInfrastructure.Services.Cache
|
|||||||
var affected = context.SaveChanges();
|
var affected = context.SaveChanges();
|
||||||
if (affected > 0)
|
if (affected > 0)
|
||||||
InternalRefresh(true);
|
InternalRefresh(true);
|
||||||
|
return affected;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
public Task UpsertAsync(TEntity entity, CancellationToken token = default)
|
public Task<int> UpsertAsync(TEntity entity, CancellationToken token = default)
|
||||||
=> SyncAsync(async (wasFree, token) => {
|
=> SyncAsync(async (wasFree, token) =>
|
||||||
|
{
|
||||||
if (dbSet.Contains(entity))
|
if (dbSet.Contains(entity))
|
||||||
dbSet.Update(entity);
|
dbSet.Update(entity);
|
||||||
else
|
else
|
||||||
dbSet.Add(entity);
|
dbSet.Add(entity);
|
||||||
var affected = await context.SaveChangesAsync(token).ConfigureAwait(false);
|
var affected = await context.SaveChangesAsync(token).ConfigureAwait(false);
|
||||||
if(affected > 0)
|
if (affected > 0)
|
||||||
await InternalRefreshAsync(true, token).ConfigureAwait(false);
|
await InternalRefreshAsync(true, token).ConfigureAwait(false);
|
||||||
|
return affected;
|
||||||
}, token);
|
}, token);
|
||||||
|
|
||||||
public void Upsert(IEnumerable<TEntity> entities)
|
public int Upsert(IEnumerable<TEntity> entities)
|
||||||
{
|
{
|
||||||
if (!entities.Any())
|
if (!entities.Any())
|
||||||
return;
|
return 0;
|
||||||
|
|
||||||
Sync((wasFree) =>
|
return Sync((wasFree) =>
|
||||||
{
|
{
|
||||||
foreach (var entity in entities)
|
foreach (var entity in entities)
|
||||||
{
|
{
|
||||||
@ -307,15 +307,17 @@ namespace AsbCloudInfrastructure.Services.Cache
|
|||||||
var affected = context.SaveChanges();
|
var affected = context.SaveChanges();
|
||||||
if (affected > 0)
|
if (affected > 0)
|
||||||
InternalRefresh(true);
|
InternalRefresh(true);
|
||||||
|
return affected;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task UpsertAsync(IEnumerable<TEntity> entities, CancellationToken token = default)
|
public Task<int> UpsertAsync(IEnumerable<TEntity> entities, CancellationToken token = default)
|
||||||
{
|
{
|
||||||
if (!entities.Any())
|
if (!entities.Any())
|
||||||
return;
|
return Task.FromResult(0);
|
||||||
|
|
||||||
await SyncAsync(async (wasFree, token) => {
|
return SyncAsync(async (wasFree, token) =>
|
||||||
|
{
|
||||||
var upsertedEntries = new List<TEntity>(entities.Count());
|
var upsertedEntries = new List<TEntity>(entities.Count());
|
||||||
foreach (var entity in entities)
|
foreach (var entity in entities)
|
||||||
{
|
{
|
||||||
@ -327,76 +329,76 @@ namespace AsbCloudInfrastructure.Services.Cache
|
|||||||
var affected = await context.SaveChangesAsync(token).ConfigureAwait(false);
|
var affected = await context.SaveChangesAsync(token).ConfigureAwait(false);
|
||||||
if (affected > 0)
|
if (affected > 0)
|
||||||
await InternalRefreshAsync(true, token).ConfigureAwait(false);
|
await InternalRefreshAsync(true, token).ConfigureAwait(false);
|
||||||
|
return affected;
|
||||||
}, token);
|
}, token);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Remove(Func<TEntity, bool> predicate)
|
public int Remove(Func<TEntity, bool> predicate)
|
||||||
=> Sync(_ =>
|
=> Sync(_ =>
|
||||||
{
|
{
|
||||||
dbSet.RemoveRange(dbSet.Where(predicate));
|
dbSet.RemoveRange(dbSet.Where(predicate));
|
||||||
var affected = context.SaveChanges();
|
var affected = context.SaveChanges();
|
||||||
if (affected > 0)
|
if (affected > 0)
|
||||||
InternalRefresh(true);
|
InternalRefresh(true);
|
||||||
|
return affected;
|
||||||
});
|
});
|
||||||
|
|
||||||
public Task RemoveAsync(Func<TEntity, bool> predicate, CancellationToken token = default)
|
public Task<int> RemoveAsync(Func<TEntity, bool> predicate, CancellationToken token = default)
|
||||||
=> SyncAsync(async (wasFree, token) => {
|
=> SyncAsync(async (wasFree, token) =>
|
||||||
|
{
|
||||||
dbSet.RemoveRange(dbSet.Where(predicate));
|
dbSet.RemoveRange(dbSet.Where(predicate));
|
||||||
var affected = await context.SaveChangesAsync(token).ConfigureAwait(false);
|
var affected = await context.SaveChangesAsync(token).ConfigureAwait(false);
|
||||||
if (affected > 0)
|
if (affected > 0)
|
||||||
await InternalRefreshAsync(true, token).ConfigureAwait(false);
|
await InternalRefreshAsync(true, token).ConfigureAwait(false);
|
||||||
|
return affected;
|
||||||
}, token);
|
}, token);
|
||||||
|
|
||||||
public TEntity Insert(TEntity entity)
|
public TEntity Insert(TEntity entity)
|
||||||
{
|
{
|
||||||
TEntity result = default;
|
return Sync(_ =>
|
||||||
Sync(_ =>
|
|
||||||
{
|
{
|
||||||
var entry = dbSet.Add(entity);
|
var entry = dbSet.Add(entity);
|
||||||
var affected = context.SaveChanges();
|
var affected = context.SaveChanges();
|
||||||
if (affected > 0)
|
if (affected > 0)
|
||||||
InternalRefresh(true);
|
InternalRefresh(true);
|
||||||
result = entry.Entity;
|
return entry.Entity;
|
||||||
});
|
});
|
||||||
return result;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task<TEntity> InsertAsync(TEntity entity, CancellationToken token = default)
|
public Task<TEntity> InsertAsync(TEntity entity, CancellationToken token = default)
|
||||||
{
|
{
|
||||||
TEntity result = default;
|
return SyncAsync(async (wasFree, token) =>
|
||||||
await SyncAsync(async (wasFree, token) =>
|
|
||||||
{
|
{
|
||||||
var entry = dbSet.Add(entity);
|
var entry = dbSet.Add(entity);
|
||||||
var affected = await context.SaveChangesAsync(token).ConfigureAwait(false);
|
var affected = await context.SaveChangesAsync(token).ConfigureAwait(false);
|
||||||
if (affected > 0)
|
if (affected > 0)
|
||||||
await InternalRefreshAsync(true, token).ConfigureAwait(false);
|
await InternalRefreshAsync(true, token).ConfigureAwait(false);
|
||||||
result = entry.Entity;
|
return entry.Entity;
|
||||||
}, token);
|
}, token);
|
||||||
return result;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public int Insert(IEnumerable<TEntity> newEntities)
|
public int Insert(IEnumerable<TEntity> newEntities)
|
||||||
{
|
{
|
||||||
int result = 0;
|
return Sync(_ =>
|
||||||
Sync(_ => {
|
{
|
||||||
dbSet.AddRange(newEntities);
|
dbSet.AddRange(newEntities);
|
||||||
result = context.SaveChanges();
|
var affected = context.SaveChanges();
|
||||||
if (result > 0)
|
if (affected > 0)
|
||||||
InternalRefresh(true);
|
InternalRefresh(true);
|
||||||
|
return affected;
|
||||||
});
|
});
|
||||||
return result;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task<int> InsertAsync(IEnumerable<TEntity> newEntities, CancellationToken token = default)
|
public Task<int> InsertAsync(IEnumerable<TEntity> newEntities, CancellationToken token = default)
|
||||||
|
{
|
||||||
|
return SyncAsync(async (wasFree, token) =>
|
||||||
{
|
{
|
||||||
int result = 0;
|
|
||||||
await SyncAsync(async (wasFree, token) => {
|
|
||||||
dbSet.AddRange(newEntities);
|
dbSet.AddRange(newEntities);
|
||||||
result = await context.SaveChangesAsync(token).ConfigureAwait(false);
|
var affected = await context.SaveChangesAsync(token).ConfigureAwait(false);
|
||||||
if (result > 0)
|
if (affected > 0)
|
||||||
await InternalRefreshAsync(true, token).ConfigureAwait(false);
|
await InternalRefreshAsync(true, token).ConfigureAwait(false);
|
||||||
|
return affected;
|
||||||
}, token);
|
}, token);
|
||||||
return result;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public IEnumerator<TEntity> GetEnumerator() => Where().GetEnumerator();
|
public IEnumerator<TEntity> GetEnumerator() => Where().GetEnumerator();
|
||||||
|
@ -102,11 +102,15 @@ namespace AsbCloudInfrastructure.Services
|
|||||||
return context.SaveChangesAsync(token);
|
return context.SaveChangesAsync(token);
|
||||||
}
|
}
|
||||||
|
|
||||||
public virtual Task<int> UpdateAsync(int id, TDto item, CancellationToken token = default)
|
public virtual async Task<int> UpdateAsync(int id, TDto item, CancellationToken token = default)
|
||||||
{
|
{
|
||||||
|
var existingEntity = await dbSet.AsNoTracking().FirstOrDefaultAsync(e => e.Id == id).ConfigureAwait(false);
|
||||||
|
if (existingEntity is null)
|
||||||
|
return 0;
|
||||||
var entity = Convert(item);
|
var entity = Convert(item);
|
||||||
|
entity.Id = id;
|
||||||
dbSet.Update(entity);
|
dbSet.Update(entity);
|
||||||
return context.SaveChangesAsync(token);
|
return await context.SaveChangesAsync(token);
|
||||||
}
|
}
|
||||||
|
|
||||||
public virtual Task<int> DeleteAsync(int id, CancellationToken token = default)
|
public virtual Task<int> DeleteAsync(int id, CancellationToken token = default)
|
||||||
|
@ -1,8 +1,9 @@
|
|||||||
using AsbCloudApp.Data;
|
using AsbCloudApp.Data;
|
||||||
using AsbCloudApp.Services;
|
using AsbCloudApp.Services;
|
||||||
using AsbCloudDb.Model;
|
using AsbCloudDb.Model;
|
||||||
|
using AsbCloudInfrastructure.Services.Cache;
|
||||||
using Mapster;
|
using Mapster;
|
||||||
using Microsoft.EntityFrameworkCore;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Threading;
|
using System.Threading;
|
||||||
@ -12,18 +13,19 @@ namespace AsbCloudInfrastructure.Services
|
|||||||
{
|
{
|
||||||
public class PermissionService : IPermissionService, IConverter<PermissionDto, Permission>
|
public class PermissionService : IPermissionService, IConverter<PermissionDto, Permission>
|
||||||
{
|
{
|
||||||
private readonly IAsbCloudDbContext db;
|
private readonly CacheTable<Permission> cachePermission;
|
||||||
|
|
||||||
public PermissionService(IAsbCloudDbContext db)
|
public PermissionService(IAsbCloudDbContext db, CacheDb cacheDb)
|
||||||
{
|
{
|
||||||
this.db = db;
|
cachePermission = cacheDb.GetCachedTable<Permission>(
|
||||||
|
(AsbCloudDbContext)db,
|
||||||
|
new string[] { nameof(Permission.PermissionInfo) });
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task<IEnumerable<PermissionDto>> GetByIdRoleAsync(int idRole, CancellationToken token)
|
public async Task<IEnumerable<PermissionDto>> GetByIdRoleAsync(int idRole, CancellationToken token)
|
||||||
{
|
{
|
||||||
var entities = await db.Permissions
|
var entities = await cachePermission
|
||||||
.Where(p => p.IdUserRole == idRole)
|
.WhereAsync(p => p.IdUserRole == idRole, token)
|
||||||
.ToListAsync(token)
|
|
||||||
.ConfigureAwait(false);
|
.ConfigureAwait(false);
|
||||||
var dto = entities.Select(Convert);
|
var dto = entities.Select(Convert);
|
||||||
return dto;
|
return dto;
|
||||||
@ -32,26 +34,36 @@ namespace AsbCloudInfrastructure.Services
|
|||||||
public Task<int> InsertRangeAsync(IEnumerable<PermissionDto> dtos, CancellationToken token)
|
public Task<int> InsertRangeAsync(IEnumerable<PermissionDto> dtos, CancellationToken token)
|
||||||
{
|
{
|
||||||
var entities = dtos.Select(Convert);
|
var entities = dtos.Select(Convert);
|
||||||
db.Permissions.AddRange(entities);
|
return cachePermission.InsertAsync(entities, token);
|
||||||
return db.SaveChangesAsync(token);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public Task<int> UpdateAsync(PermissionDto dto, CancellationToken token)
|
public async Task<int> UpdateAsync(PermissionDto dto, CancellationToken token)
|
||||||
{
|
{
|
||||||
var entity = Convert(dto);
|
var entity = Convert(dto);
|
||||||
db.Permissions.Update(entity);
|
await cachePermission.UpsertAsync(entity, token)
|
||||||
return db.SaveChangesAsync(token);
|
.ConfigureAwait(false);
|
||||||
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Task<int> DeleteAsync(int idUserRole, int idPermission, CancellationToken token)
|
public Task<int> DeleteAsync(int idUserRole, int idPermission, CancellationToken token)
|
||||||
{
|
{
|
||||||
var entities = db.Permissions.AsNoTracking()
|
bool predicate(Permission p) => p.IdUserRole == idUserRole && p.IdPermission == idPermission;
|
||||||
.Where(e => e.IdUserRole == idUserRole && e.IdPermission == idPermission)
|
return DeleteAsync(predicate, token);
|
||||||
.ToList();
|
}
|
||||||
if (!entities.Any())
|
|
||||||
return Task.FromResult(0);
|
public Task<int> DeleteAllByRoleAsync(int idUserRole, CancellationToken token)
|
||||||
db.Permissions.RemoveRange(entities);
|
{
|
||||||
return db.SaveChangesAsync(token);
|
bool predicate(Permission p) => p.IdUserRole == idUserRole;
|
||||||
|
return DeleteAsync(predicate, token);
|
||||||
|
}
|
||||||
|
|
||||||
|
private async Task<int> DeleteAsync(Func<Permission, bool> predicate, CancellationToken token)
|
||||||
|
{
|
||||||
|
var count = (await cachePermission.WhereAsync(predicate, token).ConfigureAwait(false)).Count();
|
||||||
|
if (count > 0)
|
||||||
|
await cachePermission.RemoveAsync(predicate, token)
|
||||||
|
.ConfigureAwait(false);
|
||||||
|
return count;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Permission Convert(PermissionDto src)
|
public Permission Convert(PermissionDto src)
|
||||||
|
@ -11,66 +11,97 @@ using AsbCloudApp.Services;
|
|||||||
|
|
||||||
namespace AsbCloudInfrastructure.Services
|
namespace AsbCloudInfrastructure.Services
|
||||||
{
|
{
|
||||||
public class UserRoleService : CrudServiceBase<UserRoleDto, UserRole>
|
public class UserRoleService : IUserRoleService
|
||||||
{
|
{
|
||||||
private readonly CacheTable<UserRole> cacheUserRoles;
|
private readonly CacheTable<UserRole> cacheUserRoles;
|
||||||
private readonly IPermissionService permissionService;
|
private readonly IPermissionService permissionService;
|
||||||
|
|
||||||
public UserRoleService(IAsbCloudDbContext context, CacheDb cacheDb, IPermissionService permissionService) : base(context)
|
public List<string> Incledes { get; } = new();
|
||||||
|
|
||||||
|
public UserRoleService(IAsbCloudDbContext context, CacheDb cacheDb, IPermissionService permissionService)
|
||||||
{
|
{
|
||||||
cacheUserRoles = cacheDb.GetCachedTable<UserRole>((AsbCloudDbContext)context);
|
cacheUserRoles = cacheDb.GetCachedTable<UserRole>((AsbCloudDbContext)context, new string[] { nameof(UserRole.Permissions) });
|
||||||
this.permissionService = permissionService;
|
this.permissionService = permissionService;
|
||||||
}
|
}
|
||||||
|
|
||||||
public override async Task<PaginationContainer<UserRoleDto>> GetPageAsync(int skip = 0,
|
public async Task<IEnumerable<UserRoleDto>> GetAllAsync(CancellationToken token = default)
|
||||||
int take = 32, CancellationToken token = default)
|
|
||||||
{
|
{
|
||||||
var rolesDtos = await base.GetPageAsync(skip, take, token);
|
var entities = await cacheUserRoles.WhereAsync(token)
|
||||||
return rolesDtos;
|
.ConfigureAwait(false);
|
||||||
|
var dtos = entities.Adapt<UserRoleDto>();
|
||||||
|
return dtos;
|
||||||
}
|
}
|
||||||
|
|
||||||
public override async Task<UserRoleDto> GetAsync(int id, CancellationToken token = default)
|
public async Task<UserRoleDto> GetAsync(int id, CancellationToken token = default)
|
||||||
{
|
{
|
||||||
var roleDto = await base.GetAsync(id,token);
|
var entity = await cacheUserRoles.FirstOrDefaultAsync(r=>r.Id == id, token)
|
||||||
|
.ConfigureAwait(false);
|
||||||
return roleDto;
|
var dto = entity?.Adapt<UserRoleDto>();
|
||||||
|
return dto;
|
||||||
}
|
}
|
||||||
|
|
||||||
public override async Task<int> InsertAsync(UserRoleDto dto, CancellationToken token = default)
|
public async Task<int> InsertAsync(UserRoleDto dto, CancellationToken token = default)
|
||||||
{
|
{
|
||||||
var id = await base.InsertAsync(dto, token).ConfigureAwait(false);
|
var entity = dto.Adapt<UserRole>();
|
||||||
if (dto.Permissions is not null && dto.Permissions.Any())
|
var updatedEntity = await cacheUserRoles.InsertAsync(entity, token).ConfigureAwait(false);
|
||||||
|
if (dto.Permissions?.Any() == true)
|
||||||
|
{
|
||||||
|
foreach (var permission in dto.Permissions)
|
||||||
|
permission.IdUserRole = updatedEntity.Id;
|
||||||
|
await permissionService.InsertRangeAsync(dto.Permissions, token).ConfigureAwait(false);
|
||||||
|
await cacheUserRoles.RefreshAsync(true, token)
|
||||||
|
.ConfigureAwait(false);
|
||||||
|
}
|
||||||
|
return updatedEntity?.Id ?? 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task<int> InsertRangeAsync(IEnumerable<UserRoleDto> dtos, CancellationToken token = default)
|
||||||
|
{
|
||||||
|
var entities = dtos.Adapt<UserRole>();
|
||||||
|
return await cacheUserRoles.InsertAsync(entities, token).ConfigureAwait(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task<int> UpdateAsync(int id, UserRoleDto dto, CancellationToken token = default)
|
||||||
|
{
|
||||||
|
var entity = dto.Adapt<UserRole>();
|
||||||
|
entity.Id = id;
|
||||||
|
await cacheUserRoles.UpsertAsync(entity, token)
|
||||||
|
.ConfigureAwait(false);
|
||||||
|
|
||||||
|
if(dto.Permissions is not null)
|
||||||
|
{
|
||||||
|
await permissionService.DeleteAllByRoleAsync(id, token)
|
||||||
|
.ConfigureAwait(false);
|
||||||
|
|
||||||
|
if (dto.Permissions.Any())
|
||||||
{
|
{
|
||||||
foreach (var permission in dto.Permissions)
|
foreach (var permission in dto.Permissions)
|
||||||
permission.IdUserRole = id;
|
permission.IdUserRole = id;
|
||||||
await permissionService.InsertRangeAsync(dto.Permissions, token).ConfigureAwait(false);
|
|
||||||
|
await permissionService.InsertRangeAsync(dto.Permissions, token)
|
||||||
|
.ConfigureAwait(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
await cacheUserRoles.RefreshAsync(true, token)
|
||||||
|
.ConfigureAwait(false);
|
||||||
|
}
|
||||||
|
|
||||||
return id;
|
return id;
|
||||||
}
|
}
|
||||||
|
|
||||||
public override async Task<int> UpdateAsync(int id, UserRoleDto item, CancellationToken token = default)
|
|
||||||
{
|
|
||||||
foreach (var p in item.Permissions)
|
|
||||||
p.IdUserRole = item.Id;
|
|
||||||
|
|
||||||
var result = await base.UpdateAsync(id, item, token);
|
|
||||||
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
private IEnumerable<Permission> GetNestedPermissions(UserRole role, int counter = 10)
|
private IEnumerable<Permission> GetNestedPermissions(UserRole role, int counter = 10)
|
||||||
{
|
{
|
||||||
List<Permission> permissions = role.Permissions.ToList();
|
List<Permission> permissions = role.Permissions.ToList();
|
||||||
if (role.IdParent is not null)
|
if (role.IdParent is not null)
|
||||||
{
|
{
|
||||||
if(counter == 0)
|
if (counter == 0)
|
||||||
{
|
{
|
||||||
Trace.WriteLine($"User role with id: {role.Id} has more than 10 nested childs");
|
Trace.WriteLine($"User role with id: {role.Id} has more than 10 nested childs");
|
||||||
return permissions;
|
return permissions;
|
||||||
}
|
}
|
||||||
var parentRole = cacheUserRoles.FirstOrDefault(r => r.Id == role.IdParent);
|
var parentRole = cacheUserRoles.FirstOrDefault(r => r.Id == role.IdParent);
|
||||||
|
|
||||||
if(parentRole is null)
|
if (parentRole is null)
|
||||||
return permissions;
|
return permissions;
|
||||||
|
|
||||||
var parentPermissions = GetNestedPermissions(parentRole, counter--);
|
var parentPermissions = GetNestedPermissions(parentRole, counter--);
|
||||||
@ -98,5 +129,11 @@ namespace AsbCloudInfrastructure.Services
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public Task<int> DeleteAsync(int id, CancellationToken token = default)
|
||||||
|
=> cacheUserRoles.RemoveAsync(r => r.Id == id, token);
|
||||||
|
|
||||||
|
public Task<int> DeleteAsync(IEnumerable<int> ids, CancellationToken token = default)
|
||||||
|
=> cacheUserRoles.RemoveAsync(r => ids.Contains(r.Id), token);
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -71,7 +71,7 @@ namespace AsbCloudWebApi.Controllers
|
|||||||
/// <param name="idUserRole"> id роли для удаления разрешения </param>
|
/// <param name="idUserRole"> id роли для удаления разрешения </param>
|
||||||
/// <param name="token"> Токен отмены задачи </param>
|
/// <param name="token"> Токен отмены задачи </param>
|
||||||
/// <returns></returns>
|
/// <returns></returns>
|
||||||
[HttpDelete("{idPermission}/{idRole}")]
|
[HttpDelete("{idPermission}/{idUserRole}")]
|
||||||
[ProducesResponseType(typeof(int), (int)System.Net.HttpStatusCode.OK)]
|
[ProducesResponseType(typeof(int), (int)System.Net.HttpStatusCode.OK)]
|
||||||
public async Task<IActionResult> DeleteAsync(int idUserRole, int idPermission,
|
public async Task<IActionResult> DeleteAsync(int idUserRole, int idPermission,
|
||||||
CancellationToken token = default)
|
CancellationToken token = default)
|
||||||
|
@ -13,6 +13,5 @@ namespace AsbCloudWebApi.Controllers
|
|||||||
public AdminPermissionInfoController(ICrudService<PermissionInfoDto> permissionInfoService)
|
public AdminPermissionInfoController(ICrudService<PermissionInfoDto> permissionInfoService)
|
||||||
:base(permissionInfoService)
|
:base(permissionInfoService)
|
||||||
{}
|
{}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -10,8 +10,9 @@ namespace AsbCloudWebApi.Controllers
|
|||||||
[Authorize]
|
[Authorize]
|
||||||
public class AdminUserRoleController : CrudController<UserRoleDto, ICrudService<UserRoleDto>>
|
public class AdminUserRoleController : CrudController<UserRoleDto, ICrudService<UserRoleDto>>
|
||||||
{
|
{
|
||||||
public AdminUserRoleController(ICrudService<UserRoleDto> service)
|
public AdminUserRoleController(IUserRoleService service)
|
||||||
: base(service)
|
:base(service)
|
||||||
{ }
|
{
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -30,24 +30,6 @@ namespace AsbCloudWebApi.Controllers
|
|||||||
this.service = service;
|
this.service = service;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Получить страницу с записями в PaginationContainer
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="skip">пропустить skip записей</param>
|
|
||||||
/// <param name="take">получить take записей</param>
|
|
||||||
/// <param name="token">CancellationToken</param>
|
|
||||||
/// <returns>страница с записями в PaginationContainer</returns>
|
|
||||||
[HttpGet()]
|
|
||||||
public virtual async Task<ActionResult<PaginationContainer<T>>> GetPage(int skip = 0, int take = 32,
|
|
||||||
CancellationToken token = default)
|
|
||||||
{
|
|
||||||
if (!Roles.Any(role => User.IsInRole(role)))
|
|
||||||
return Forbid();
|
|
||||||
|
|
||||||
var result = await service.GetPageAsync(skip, take, token).ConfigureAwait(false);
|
|
||||||
return Ok(result);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Получить все записи
|
/// Получить все записи
|
||||||
/// </summary>
|
/// </summary>
|
||||||
@ -111,6 +93,8 @@ namespace AsbCloudWebApi.Controllers
|
|||||||
return Forbid();
|
return Forbid();
|
||||||
|
|
||||||
var result = await service.UpdateAsync(id, value, token).ConfigureAwait(false);
|
var result = await service.UpdateAsync(id, value, token).ConfigureAwait(false);
|
||||||
|
if (result == 0)
|
||||||
|
return BadRequest($"id:{id} does not exist in the db");
|
||||||
return Ok(result);
|
return Ok(result);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -131,4 +115,6 @@ namespace AsbCloudWebApi.Controllers
|
|||||||
return Ok(result);
|
return Ok(result);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user