diff --git a/AsbCloudInfrastructure/Repository/UserRepository.cs b/AsbCloudInfrastructure/Repository/UserRepository.cs index fe8979b7..d5023f90 100644 --- a/AsbCloudInfrastructure/Repository/UserRepository.cs +++ b/AsbCloudInfrastructure/Repository/UserRepository.cs @@ -59,30 +59,36 @@ namespace AsbCloudInfrastructure.Repository public async Task> 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(); - 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 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() - .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 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> 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 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 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> FromCacheAsync(IQueryable query, string tag, TimeSpan obsolescence, Func convert, CancellationToken token) - where TEntity : class + private void DropCacheUsers() + => memoryCache.Remove(userCacheTag); + + private IEnumerable GetCacheUser() { - async Task factory(CancellationToken token) - => await query.ToArrayAsync(token); - var cache = await GetOrAddCacheAsync(tag, factory, obsolescence, token); - return cache.Select(convert); - } - public async Task> FromCacheAsync(IQueryable query, string tag, TimeSpan obsolescence, CancellationToken token) - where TEntity : class - { - async Task 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 FromCache(IQueryable query, string tag, TimeSpan obsolescence, Func convert) - where TEntity : class + + private Task> GetCacheUserAsync(CancellationToken token) { - TEntity[] factory() - => query.ToArray(); - var cache = GetOrAddCache(tag, factory, obsolescence); - return cache.Select(convert); - } - public IEnumerable FromCache(IQueryable 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 GetOrAddCacheAsync(string tag, Func> 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(string tag, Func 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(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();