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)
{
var dtos = (await GetCacheUserAsync(token)).ToList();
if (dtos is null)
var users = await GetCacheUserAsync(token);
if (users is null)
return Enumerable.Empty<UserExtendedDto>();
for (var i = 0; i < dtos.Count; i++)
dtos[i].RoleNames = GetRolesNamesByIdUser(dtos[i].Id);
var dtos = users
.Select(d => Convert(d));
foreach(var dto in dtos)
{
dto.RoleNames = GetRolesNamesByIdUser(dto.Id);
};
return dtos;
}
public UserExtendedDto? GetOrDefault(int id)
{
var dto = GetCacheUser().FirstOrDefault(u => u.Id == id);
if (dto is null)
var user = GetCacheUser().FirstOrDefault(u => u.Id == id);
if (user is null)
return null;
var entity = Convert(dto);
var dto = Convert(user);
dto.RoleNames = GetRolesNamesByIdUser(dto.Id);
return dto;
}
public async Task<UserExtendedDto?> GetOrDefaultAsync(int id, CancellationToken token)
{
var dto = (await GetCacheUserAsync(token)).FirstOrDefault(u => u.Id == id);
if (dto is null)
{
var user = (await GetCacheUserAsync(token)).FirstOrDefault(u => u.Id == id);
if (user is null)
return null;
var dto = Convert(user);
dto.RoleNames = GetRolesNamesByIdUser(dto.Id);
return dto;
}
@ -102,29 +108,33 @@ namespace AsbCloudInfrastructure.Repository
var userRoles = await userRoleRepository.GetByNamesAsync(dto.RoleNames, token).ConfigureAwait(false);
await UpdateRolesCacheForUserAsync(dto.Id, userRoles, token);
var entity = Convert(dto);
var local = dbContext.Set<User>()
.Local
.FirstOrDefault(entry => entry.Id.Equals(entity.Id));
if (local is not null)
{
dbContext.Entry(local).State = EntityState.Detached;
}
dbContext.Entry(entity).State = EntityState.Modified;
await dbContext.SaveChangesAsync(token);
var entity = dbContext.Users.FirstOrDefault(u => u.Id == dto.Id);
if (entity is not null)
{
var user = Convert(dto);
entity.Id = user.Id;
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);
}
DropCacheUsers();
return entity.Id;
return entity!.Id;
}
public async Task<int> DeleteAsync(int id, CancellationToken token)
{
var dto = (await GetCacheUserAsync(token)).FirstOrDefault(u => u.Id == id);
if (dto is null)
return 0;
var entity = Convert(dto);
var result = dbContext.Users.Remove(entity);
var user = (await GetCacheUserAsync(token)).FirstOrDefault(u => u.Id == id);
if (user is null)
return 0;
var result = dbContext.Users.Remove(user);
await dbContext.SaveChangesAsync(token);
DropCacheUsers();
return result.Entity.Id;
@ -174,33 +184,23 @@ namespace AsbCloudInfrastructure.Repository
if (existingUserDto is not null)
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()
{
var query = dbContext.RelationUserUserRoles
var cache = memoryCache.GetOrCreate(userCacheTag, cacheEntry =>
{
cacheEntry.AbsoluteExpirationRelativeToNow = cacheObsolence;
cacheEntry.SlidingExpiration = cacheObsolence;
var query = dbContext.RelationUserUserRoles
.Include(r => r.UserRole)
.Include(r => r.User);
return FromCache(query, relationUserUserRoleCacheTag, cacheObsolence);
}
var entities = query.ToArray();
return entities;
});
return cache;
}
private void DropCacheRelationUserUserRoleCacheTag()
{
memoryCache.Remove(relationUserUserRoleCacheTag);
@ -222,72 +222,40 @@ namespace AsbCloudInfrastructure.Repository
DropCacheRelationUserUserRoleCacheTag();
}
public async Task<IEnumerable<TModel>> FromCacheAsync<TEntity, TModel>(IQueryable<TEntity> query, string tag, TimeSpan obsolescence, Func<TEntity, TModel> convert, CancellationToken token)
where TEntity : class
private void DropCacheUsers()
=> memoryCache.Remove(userCacheTag);
private IEnumerable<User> GetCacheUser()
{
async Task<TEntity[]> factory(CancellationToken token)
=> 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)
=> await query.ToArrayAsync(token);
var cache = await GetOrAddCacheAsync(tag, factory, obsolescence, token);
var cache = memoryCache.GetOrCreate(userCacheTag, cacheEntry =>
{
cacheEntry.AbsoluteExpirationRelativeToNow = cacheObsolence;
cacheEntry.SlidingExpiration = cacheObsolence;
var query = dbContext.Users
.Include(r => r.Company)
.Include(r => r.RelationUsersUserRoles);
var entities = query.ToArray();
return entities;
});
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()
=> 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()
=> query.ToArray();
var cache = GetOrAddCache(tag, factory, obsolescence);
var cache = memoryCache.GetOrCreateAsync(userCacheTag, async (cacheEntry) =>
{
cacheEntry.AbsoluteExpirationRelativeToNow = cacheObsolence;
cacheEntry.SlidingExpiration = cacheObsolence;
var query = dbContext.Users
.Include(r => r.Company)
.Include(r => r.RelationUsersUserRoles);
var entities = await query.ToArrayAsync(token);
return entities.AsEnumerable();
});
return cache;
}
private async Task<TEntity[]> GetOrAddCacheAsync<TEntity>(string tag, Func<CancellationToken, Task<TEntity[]>> valueFactoryAsync, TimeSpan obsolete, CancellationToken token)
{
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)
protected User Convert(UserExtendedDto dto)
{
var entity = dto.Adapt<User>(userTypeAdapterConfig);
if (string.IsNullOrEmpty(entity.PasswordHash))
@ -295,6 +263,8 @@ namespace AsbCloudInfrastructure.Repository
return entity;
}
protected virtual UserExtendedDto Convert(User entity)
{
var dto = entity.Adapt<UserExtendedDto>();