using Microsoft.EntityFrameworkCore; using Microsoft.Extensions.Logging; using PARR.Core.Common.Interfaces; using PARR.Core.Repositories.Interfaces; using PARR.DAL.Context; using PARR.DAL.Contracts; using PARR.DAL.Repositories.Base; using PARR.Domain.Entities; namespace PARR.DAL.Repositories { internal class WeekendDayRepository : BaseRepository, IWeekendDayRepository { private readonly IRedisCacheService redisCacheService; private readonly SettingsFromDb settings; public WeekendDayRepository( DataContext dataContext, ILogger logger, IRedisCacheService redisCacheService, SettingsFromDb settings ) : base(logger, dataContext) { this.redisCacheService = redisCacheService; this.settings = settings; } public IQueryable GetWeekends(DateOnly start, DateOnly end) { return EntitySet.Where(t => t.Date >= start && t.Date <= end).AsNoTracking().Select(t => t.Date); } public async Task IsWorkDayAsync(DateOnly date, bool useCache = false) { if (useCache) { // смотрим, есть ли в кэше рабочий день var workdayInCache = await redisCacheService.GetCachedDataAsync(GetWorkDayKey(date)); if (workdayInCache != null) return true; // смотрим, есть ли в кэше выходной день var weekendInCache = await redisCacheService.GetCachedDataAsync(GetWeekendKey(date)); if (weekendInCache != null) return false; } var weekendInDb = await EntitySet.FirstOrDefaultAsync(t => t.Date == date); var isWorkday = weekendInDb == null; //сохраняем всегда в КЭШ значение выходного и рабочего дня var cacheKey = isWorkday ? GetWorkDayKey(date) : GetWeekendKey(date); await redisCacheService.SetCachedDataAsync(cacheKey, date, settings.WeekendCacheTtl); return isWorkday; } public override async Task CreateAsync(WeekendDay obj) { // При создании выходного дня, смотрим, был ли он в кэше, если был, удаляем await redisCacheService.DeleteCachedDataAsync(GetWeekendKey(obj.Date)); await redisCacheService.DeleteCachedDataAsync(GetWorkDayKey(obj.Date)); return await base.CreateAsync(obj); } public override bool Delete(WeekendDay obj) { // При создании выходного дня, смотрим, был ли он в кэше, если был, удаляем redisCacheService.DeleteCachedData(GetWeekendKey(obj.Date)); redisCacheService.DeleteCachedData(GetWorkDayKey(obj.Date)); return base.Delete(obj); } public override async Task DeleteAsync(Guid id) { var exist = await GetAsync(id); if (exist == null) { logger.LogError($"Ошибка при удалении из БД. Не найдена запись в БД с id: {id}"); return false; } return Delete(exist); } private string GetWeekendKey(DateOnly day) { // return $"weekend_{day.ToString("yyyy-MM-dd")}"; return redisCacheService.GetKey(new[] { "weekend", day.ToString("yyyy-MM-dd") }); } private string GetWorkDayKey(DateOnly day) { //return $"workday_{day.ToString("yyyy-MM-dd")}"; return redisCacheService.GetKey(new[] { "workday", day.ToString("yyyy-MM-dd") }); } } }