private async Task <Either <ActionResult, TableBuilderResultViewModel> > Query( Release release, ObservationQueryContext queryContext, CancellationToken cancellationToken) { return(await _statisticsPersistenceHelper.CheckEntityExists <Subject>(queryContext.SubjectId) .OnSuccessDo(CheckCanViewSubjectData) .OnSuccess(async() => { if (await GetMaximumTableCellCount(queryContext) > _options.MaxTableCellsAllowed) { return ValidationUtils.ValidationResult(QueryExceedsMaxAllowableTableSize); } var matchedObservationIds = (await _observationService.GetMatchedObservations(queryContext, cancellationToken)) .Select(row => row.Id); var observations = await _context .Observation .AsNoTracking() .Include(o => o.Location) .Include(o => o.FilterItems) .Where(o => matchedObservationIds.Contains(o.Id)) .ToListAsync(cancellationToken); if (!observations.Any()) { return new TableBuilderResultViewModel(); } return await _resultSubjectMetaService .GetSubjectMeta( release.Id, queryContext, observations) .OnSuccess(subjectMetaViewModel => { return new TableBuilderResultViewModel { SubjectMeta = subjectMetaViewModel, Results = observations.Select(observation => _resultBuilder.BuildResult(observation, queryContext.Indicators)) }; }); })); }
private async Task <SubjectMetaViewModel> GetSubjectMetaViewModelFromQuery( ObservationQueryContext query, CancellationToken cancellationToken) { SubjectMetaQueryStep?subjectMetaStep = null; if (!query.LocationIds.IsNullOrEmpty() && query.TimePeriod == null) { subjectMetaStep = SubjectMetaQueryStep.GetTimePeriods; } else if (query.TimePeriod != null && query.Filters == null) { subjectMetaStep = SubjectMetaQueryStep.GetFilterItems; } // Only data relevant to the step being executed in the table tool needs to be returned, so only the // minimum requisite DB calls for the task are performed. switch (subjectMetaStep) { case SubjectMetaQueryStep.GetTimePeriods: { var stopwatch = Stopwatch.StartNew(); var observations = _context .Observation .AsNoTracking() .Where(o => o.SubjectId == query.SubjectId && query.LocationIds.Contains(o.LocationId)); var timePeriods = GetTimePeriods(observations); _logger.LogTrace("Got Time Periods in {Time} ms", stopwatch.Elapsed.TotalMilliseconds); return(new SubjectMetaViewModel { TimePeriod = timePeriods }); } case SubjectMetaQueryStep.GetFilterItems: { var stopwatch = Stopwatch.StartNew(); var observations = await _observationService.GetMatchedObservations(query, cancellationToken); _logger.LogTrace("Got Observations in {Time} ms", stopwatch.Elapsed.TotalMilliseconds); stopwatch.Restart(); var filterItems = await _filterItemRepository.GetFilterItemsFromMatchedObservationIds(query.SubjectId, observations); var filters = BuildFilterHierarchy(filterItems); _logger.LogTrace("Got Filters in {Time} ms", stopwatch.Elapsed.TotalMilliseconds); stopwatch.Restart(); var indicators = GetIndicators(query.SubjectId); _logger.LogTrace("Got Indicators in {Time} ms", stopwatch.Elapsed.TotalMilliseconds); return(new SubjectMetaViewModel { Filters = filters, Indicators = indicators, }); } default: throw new ArgumentOutOfRangeException($"{nameof(subjectMetaStep)}", "Unable to determine which SubjectMeta information has requested"); } }