new change to cache methods

This commit is contained in:
eugeniy_ivanov 2023-02-13 15:39:17 +05:00
parent 1694ef8569
commit 95790af1f6

View File

@ -59,30 +59,36 @@ namespace AsbCloudInfrastructure.Repository
public async Task<IEnumerable<UserExtendedDto>> GetAllAsync(CancellationToken token) public async Task<IEnumerable<UserExtendedDto>> GetAllAsync(CancellationToken token)
{ {
var dtos = (await GetCacheUserAsync(token)).ToList(); var users = await GetCacheUserAsync(token);
if (dtos is null) if (users is null)
return Enumerable.Empty<UserExtendedDto>(); return Enumerable.Empty<UserExtendedDto>();
for (var i = 0; i < dtos.Count; i++) var dtos = users
dtos[i].RoleNames = GetRolesNamesByIdUser(dtos[i].Id); .Select(d => Convert(d));
foreach(var dto in dtos)
{
dto.RoleNames = GetRolesNamesByIdUser(dto.Id);
};
return dtos; return dtos;
} }
public UserExtendedDto? GetOrDefault(int id) public UserExtendedDto? GetOrDefault(int id)
{ {
var dto = GetCacheUser().FirstOrDefault(u => u.Id == id); var user = GetCacheUser().FirstOrDefault(u => u.Id == id);
if (dto is null) if (user is null)
return null; return null;
var entity = Convert(dto); var dto = Convert(user);
dto.RoleNames = GetRolesNamesByIdUser(dto.Id); dto.RoleNames = GetRolesNamesByIdUser(dto.Id);
return dto; return dto;
} }
public async Task<UserExtendedDto?> GetOrDefaultAsync(int id, CancellationToken token) public async Task<UserExtendedDto?> GetOrDefaultAsync(int id, CancellationToken token)
{ {
var dto = (await GetCacheUserAsync(token)).FirstOrDefault(u => u.Id == id); var user = (await GetCacheUserAsync(token)).FirstOrDefault(u => u.Id == id);
if (dto is null) if (user is null)
return null; return null;
var dto = Convert(user);
dto.RoleNames = GetRolesNamesByIdUser(dto.Id); dto.RoleNames = GetRolesNamesByIdUser(dto.Id);
return dto; return dto;
} }
@ -102,29 +108,33 @@ namespace AsbCloudInfrastructure.Repository
var userRoles = await userRoleRepository.GetByNamesAsync(dto.RoleNames, token).ConfigureAwait(false); var userRoles = await userRoleRepository.GetByNamesAsync(dto.RoleNames, token).ConfigureAwait(false);
await UpdateRolesCacheForUserAsync(dto.Id, userRoles, token); await UpdateRolesCacheForUserAsync(dto.Id, userRoles, token);
var entity = Convert(dto); var entity = dbContext.Users.FirstOrDefault(u => u.Id == dto.Id);
if (entity is not null)
var local = dbContext.Set<User>()
.Local
.FirstOrDefault(entry => entry.Id.Equals(entity.Id));
if (local is not null)
{ {
dbContext.Entry(local).State = EntityState.Detached; var user = Convert(dto);
} entity.Id = user.Id;
dbContext.Entry(entity).State = EntityState.Modified; entity.Company = user.Company;
entity.Name = user.Name;
entity.Email = user.Email;
entity.Phone = user.Phone;
entity.Surname = user.Surname;
entity.Patronymic = user.Patronymic;
entity.Position = user.Position;
entity.IdCompany = user.IdCompany;
entity.IdState = user.IdState;
entity.RelationUsersUserRoles = user.RelationUsersUserRoles;
await dbContext.SaveChangesAsync(token); await dbContext.SaveChangesAsync(token);
}
DropCacheUsers(); DropCacheUsers();
return entity.Id; return entity!.Id;
} }
public async Task<int> DeleteAsync(int id, CancellationToken token) public async Task<int> DeleteAsync(int id, CancellationToken token)
{ {
var dto = (await GetCacheUserAsync(token)).FirstOrDefault(u => u.Id == id); var user = (await GetCacheUserAsync(token)).FirstOrDefault(u => u.Id == id);
if (dto is null) if (user is null)
return 0; return 0;
var result = dbContext.Users.Remove(user);
var entity = Convert(dto);
var result = dbContext.Users.Remove(entity);
await dbContext.SaveChangesAsync(token); await dbContext.SaveChangesAsync(token);
DropCacheUsers(); DropCacheUsers();
return result.Entity.Id; return result.Entity.Id;
@ -176,30 +186,20 @@ namespace AsbCloudInfrastructure.Repository
throw new ArgumentInvalidException($"Login {login} is busy by {existingUserDto.MakeDisplayName()}, id{existingUserDto.Id}", nameof(login)); throw new ArgumentInvalidException($"Login {login} is busy by {existingUserDto.MakeDisplayName()}, id{existingUserDto.Id}", nameof(login));
} }
private async Task<IEnumerable<UserExtendedDto>> GetCacheUserAsync(CancellationToken token)
{
var query = dbContext.Users
.Include(r => r.Company)
.Include(r => r.RelationUsersUserRoles);
return await FromCacheAsync(query, userCacheTag, cacheObsolence, Convert, token);
}
private IEnumerable<UserExtendedDto> GetCacheUser()
{
var query = dbContext.Users
.Include(r => r.Company)
.Include(r => r.RelationUsersUserRoles);
return FromCache(query, userCacheTag, cacheObsolence, Convert);
}
private void DropCacheUsers()
{
memoryCache.Remove(userCacheTag);
}
private IEnumerable<RelationUserUserRole> GetCachRelationUserUserRoleCacheTag() private IEnumerable<RelationUserUserRole> GetCachRelationUserUserRoleCacheTag()
{ {
var cache = memoryCache.GetOrCreate(userCacheTag, cacheEntry =>
{
cacheEntry.AbsoluteExpirationRelativeToNow = cacheObsolence;
cacheEntry.SlidingExpiration = cacheObsolence;
var query = dbContext.RelationUserUserRoles var query = dbContext.RelationUserUserRoles
.Include(r => r.UserRole) .Include(r => r.UserRole)
.Include(r => r.User); .Include(r => r.User);
return FromCache(query, relationUserUserRoleCacheTag, cacheObsolence); var entities = query.ToArray();
return entities;
});
return cache;
} }
private void DropCacheRelationUserUserRoleCacheTag() private void DropCacheRelationUserUserRoleCacheTag()
{ {
@ -222,72 +222,40 @@ namespace AsbCloudInfrastructure.Repository
DropCacheRelationUserUserRoleCacheTag(); DropCacheRelationUserUserRoleCacheTag();
} }
public async Task<IEnumerable<TModel>> FromCacheAsync<TEntity, TModel>(IQueryable<TEntity> query, string tag, TimeSpan obsolescence, Func<TEntity, TModel> convert, CancellationToken token) private void DropCacheUsers()
where TEntity : class => memoryCache.Remove(userCacheTag);
private IEnumerable<User> GetCacheUser()
{ {
async Task<TEntity[]> factory(CancellationToken token) var cache = memoryCache.GetOrCreate(userCacheTag, cacheEntry =>
=> await query.ToArrayAsync(token);
var cache = await GetOrAddCacheAsync(tag, factory, obsolescence, token);
return cache.Select(convert);
}
public async Task<IEnumerable<TEntity>> FromCacheAsync<TEntity>(IQueryable<TEntity> query, string tag, TimeSpan obsolescence, CancellationToken token)
where TEntity : class
{ {
async Task<TEntity[]> factory(CancellationToken token) cacheEntry.AbsoluteExpirationRelativeToNow = cacheObsolence;
=> await query.ToArrayAsync(token); cacheEntry.SlidingExpiration = cacheObsolence;
var cache = await GetOrAddCacheAsync(tag, factory, obsolescence, token); var query = dbContext.Users
.Include(r => r.Company)
.Include(r => r.RelationUsersUserRoles);
var entities = query.ToArray();
return entities;
});
return cache; return cache;
} }
public IEnumerable<TModel> FromCache<TEntity, TModel>(IQueryable<TEntity> query, string tag, TimeSpan obsolescence, Func<TEntity, TModel> convert)
where TEntity : class private Task<IEnumerable<User>> GetCacheUserAsync(CancellationToken token)
{ {
TEntity[] factory() var cache = memoryCache.GetOrCreateAsync(userCacheTag, async (cacheEntry) =>
=> query.ToArray();
var cache = GetOrAddCache(tag, factory, obsolescence);
return cache.Select(convert);
}
public IEnumerable<TEntity> FromCache<TEntity>(IQueryable<TEntity> query, string tag, TimeSpan obsolescence)
where TEntity : class
{ {
TEntity[] factory() cacheEntry.AbsoluteExpirationRelativeToNow = cacheObsolence;
=> query.ToArray(); cacheEntry.SlidingExpiration = cacheObsolence;
var cache = GetOrAddCache(tag, factory, obsolescence); var query = dbContext.Users
.Include(r => r.Company)
.Include(r => r.RelationUsersUserRoles);
var entities = await query.ToArrayAsync(token);
return entities.AsEnumerable();
});
return cache; return cache;
} }
private async Task<TEntity[]> GetOrAddCacheAsync<TEntity>(string tag, Func<CancellationToken, Task<TEntity[]>> valueFactoryAsync, TimeSpan obsolete, CancellationToken token)
{ protected User Convert(UserExtendedDto dto)
memoryCache.TryGetValue(tag, out TEntity[]? cached);
if (cached == null)
{
var values = await valueFactoryAsync(token);
if (values != null)
{
memoryCache.Set(tag, values, new MemoryCacheEntryOptions().SetAbsoluteExpiration(obsolete));
}
return values!;
}
return cached;
}
private TEntity[] GetOrAddCache<TEntity>(string tag, Func<TEntity[]> valueFactory, TimeSpan obsolete)
{
memoryCache.TryGetValue(tag, out TEntity[]? cached);
if (cached == null)
{
var values = valueFactory();
if (values != null)
{
memoryCache.Set(tag, values, new MemoryCacheEntryOptions().SetAbsoluteExpiration(obsolete));
}
return values!;
}
return cached;
}
protected virtual User Convert(UserExtendedDto dto)
{ {
var entity = dto.Adapt<User>(userTypeAdapterConfig); var entity = dto.Adapt<User>(userTypeAdapterConfig);
if (string.IsNullOrEmpty(entity.PasswordHash)) if (string.IsNullOrEmpty(entity.PasswordHash))
@ -295,6 +263,8 @@ namespace AsbCloudInfrastructure.Repository
return entity; return entity;
} }
protected virtual UserExtendedDto Convert(User entity) protected virtual UserExtendedDto Convert(User entity)
{ {
var dto = entity.Adapt<UserExtendedDto>(); var dto = entity.Adapt<UserExtendedDto>();