protected void InitializeCaches() { if (!_cachesInitialized) { using (var dbContext = _dbContextFactory.Create()) { _programmeDictionaryCache = new ProgrammeDictionaryCache(dbContext, trackingChanges: false); _programmeDictionaryCache.Load(); _programmeCategoryCache = new ProgrammeCategoryCache(dbContext, trackingChanges: false); _programmeCategoryCache.Load(); _scheduleCache = new SqlServerEntityCache <int, ScheduleEntity>(dbContext, x => x.ScheduleUniqueKey, trackingChanges: false); _scheduleCache.Load(); _salesAreaCache = new SqlServerEntityCache <string, SalesArea>(dbContext, x => x.Name, trackingChanges: false); _salesAreaCache.Load(); _categoryHierarchyNames = new HashSet <string>(dbContext.Query <ProgrammeCategoryHierarchy>().Select(x => x.Name) .AsEnumerable()); } _cachesInitialized = true; } }
public ProgrammeEpisodeDomainModelHandler( ISqlServerTestDbContext dbContext, IMapper mapper) : base(dbContext, mapper) { _mapper = mapper; _programmeDictionaryCache = new ProgrammeDictionaryCache(dbContext); }
public ProgrammeRepository( ISqlServerTenantDbContext dbContext, ISqlServerDbContextFactory <ISqlServerTenantDbContext> dbContextFactory, IFullTextSearchConditionBuilder searchConditionBuilder, ISqlServerSalesAreaByIdCacheAccessor salesAreaByIdCache, ISqlServerSalesAreaByNameCacheAccessor salesAreaByNameCache, IMapper mapper) { _dbContext = dbContext; _dbContextFactory = dbContextFactory; _searchConditionBuilder = searchConditionBuilder; _salesAreaByIdCache = salesAreaByIdCache; _salesAreaByNameCache = salesAreaByNameCache; _mapper = mapper; _programmeDictionaryCache = new ProgrammeDictionaryCache(_dbContext, preloadData: false); _programmeCategoryCache = new ProgrammeCategoryCache(_dbContext); }
public void Handle(IBulkProgrammeUpdated command) { Task.Run(async() => { var actionBlock = new ActionBlock <(int Id, IProgrammeUpdated UpdateInfo)>( x => UpdateProgrammeAsync(x.Id, x.UpdateInfo), new ExecutionDataflowBlockOptions { MaxDegreeOfParallelism = 1 }); using (var dbContext = _dbContextFactory.Create()) { var programmeDictionaryCache = new ProgrammeDictionaryCache(dbContext); try { foreach (var cmd in command.Data.GroupBy(x => x.ExternalReference).Select(x => x.Last())) { var programmDictionary = programmeDictionaryCache.Get(cmd.ExternalReference); if (programmDictionary is null) { _logger?.Warn($" Handler: {GetType().Name}. Invalid programme external reference, updating skipped", cmd.ExternalReference); continue; } programmDictionary.Name = cmd.ProgrammeName; programmDictionary.Description = cmd.Description; programmDictionary.Classification = cmd.Classification; _ = await actionBlock.SendAsync((programmDictionary.Id, cmd)).ConfigureAwait(false); await dbContext.SaveChangesAsync().ConfigureAwait(false); } } catch (Exception ex) { actionBlock.Complete(); var exceptions = await actionBlock.Completion.WaitWithTaskExceptionGatheringAsync().ConfigureAwait(false); if (exceptions.Count == 0) { throw; } throw new AggregateException( "Updating of programmes finished with some errors. See inner exception for more details.", new AggregateException(new[] { ex }.Union(exceptions))); } } actionBlock.Complete(); await actionBlock.Completion.AggregateExceptions().ConfigureAwait(false); async Task UpdateProgrammeAsync(int id, IProgrammeUpdated updateInfo) { using (var dbContext = _dbContextFactory.Create()) { var programmes = await dbContext.Query <ProgrammeEntity>() .Where(p => p.ProgrammeDictionaryId == id && p.LiveBroadcast != updateInfo.LiveBroadcast) .Select(p => new ProgrammeEntity { Id = p.Id }).AsNoTracking().ToArrayAsync() .ConfigureAwait(false); foreach (var programme in programmes) { var entry = dbContext.Specific.Attach(programme); entry.Property(x => x.LiveBroadcast).CurrentValue = updateInfo.LiveBroadcast; } await dbContext.SaveChangesAsync().ConfigureAwait(false); } } }).GetAwaiter().GetResult(); }
public void Add(IEnumerable <Programme> item) { using (var operationDbContext = _dbContextFactory.Create()) { var prgDictCache = new ProgrammeDictionaryCache(operationDbContext, trackingChanges: false); var prgCatCache = new ProgrammeCategoryCache(operationDbContext, trackingChanges: false); var prgDictToProcess = new HashSet <Entities.Tenant.ProgrammeDictionary>(); var prgCatToProcess = new List <ProgrammeCategory>(); var prgToProcess = new List <Entities.Tenant.Programmes.Programme>(); var prgCatLinkToProcess = new List <ProgrammeCategoryLink>(); var prgDictEpisodeToProcess = new HashSet <ProgrammeEpisode>(); foreach (var model in item) { var programmeDictionary = prgDictCache.Get(model.ExternalReference); if (programmeDictionary is null) { programmeDictionary = _mapper.Map <Entities.Tenant.ProgrammeDictionary>(model); prgDictCache.Add(programmeDictionary); } else { programmeDictionary.Name = model.ProgrammeName; programmeDictionary.Description = model.Description; programmeDictionary.Classification = model.Classification; } _ = prgDictToProcess.Add(programmeDictionary); var programme = _mapper.Map <Entities.Tenant.Programmes.Programme>(model, opts => opts.UseEntityCache(_salesAreaByNameCache)); if (programme.Id == Guid.Empty) { programme.Id = Guid.NewGuid(); } programme.ProgrammeDictionary = programmeDictionary; prgToProcess.Add(programme); foreach (var catName in model.ProgrammeCategories ?? Enumerable.Empty <string>()) { var category = prgCatCache.GetOrAdd(catName, key => { var newCat = new ProgrammeCategory { Name = key }; prgCatToProcess.Add(newCat); return(newCat); }); if (programme.ProgrammeCategoryLinks.All(x => !string.Equals(x.ProgrammeCategory.Name, category.Name))) { var link = new ProgrammeCategoryLink { ProgrammeCategory = category, Programme = programme, ProgrammeId = programme.Id }; programme.ProgrammeCategoryLinks.Add(link); prgCatLinkToProcess.Add(link); } } if (!(model.Episode is null)) { var episode = programmeDictionary.ProgrammeEpisodes.FirstOrDefault(x => x.Number == model.Episode.Number); if (episode is null) { episode = new ProgrammeEpisode { Name = model.Episode.Name, Number = model.Episode.Number, ProgrammeDictionary = programmeDictionary }; programmeDictionary.ProgrammeEpisodes.Add(episode); } else { episode.Name = model.Episode.Name; } programme.Episode = episode; _ = prgDictEpisodeToProcess.Add(episode); } } using (var transaction = operationDbContext.Specific.Database.BeginTransaction()) { operationDbContext.BulkInsertEngine.BulkInsertOrUpdate(prgDictToProcess.ToList(), new BulkInsertOptions { PreserveInsertOrder = true, SetOutputIdentity = true }); foreach (var episode in prgDictEpisodeToProcess) { episode.ProgrammeDictionaryId = episode.ProgrammeDictionary.Id; } operationDbContext.BulkInsertEngine.BulkInsertOrUpdate(prgDictEpisodeToProcess.ToList(), new BulkInsertOptions { PreserveInsertOrder = true, SetOutputIdentity = true }); operationDbContext.BulkInsertEngine.BulkInsert(prgCatToProcess, new BulkInsertOptions { PreserveInsertOrder = true, SetOutputIdentity = true }); foreach (var prg in prgToProcess) { prg.ProgrammeDictionaryId = prg.ProgrammeDictionary.Id; prg.EpisodeId = prg.Episode?.Id; } operationDbContext.BulkInsertEngine.BulkInsert(prgToProcess, new BulkInsertOptions { PreserveInsertOrder = true }); foreach (var catLink in prgCatLinkToProcess) { catLink.ProgrammeCategoryId = catLink.ProgrammeCategory.Id; } operationDbContext.BulkInsertEngine.BulkInsert(prgCatLinkToProcess); transaction.Commit(); } var actionBuilder = new BulkInsertActionBuilder <Entities.Tenant.Programmes.Programme>(prgToProcess, _mapper); actionBuilder.TryToUpdate(item, opts => opts.UseEntityCache(_salesAreaByIdCache)); actionBuilder.Build()?.Execute(); } }