public async Task <SearchResult <Document> > Search(SearchRequest searchRequest, CancellationToken cancellationToken) { var request = (DocumentSearchRequest)searchRequest ?? throw new ArgumentNullException(nameof(searchRequest)); using (var db = _dbContextFactory.Create()) { var query = db.GetTable <DbDocument>().AsQueryable(); if (request.Uid != null) { query = query.Where(x => x.Uid == request.Uid); } var data = await Materialize( query.Apply(request, x => x.DocumentDate, SortOrder.Descending), cancellationToken); // todo: preload fields for multiple items if (request.IncludeFields) { foreach (var item in data) { if (item.Uid.HasValue) { // todo: load metadata once for each document type var metadata = await _fieldMetadataRepository.Search(new MetadataSearchRequest { EntityTypeCode = DocumentType.EntityTypeCode, EntityUid = item.DocumentTypeUid, IsActive = true, SkipPaging = true }, cancellationToken); var fields = await _fieldDataRepository.Search(new FieldDataSearchRequest { Metadata = metadata.Rows, EntityTypeCode = Document.TypeCode, EntityUids = new[] { item.Uid.Value } }, cancellationToken); item.Fields = fields.Rows.SingleOrDefault(); } } } return(new SearchResult <Document> { TotalCount = query.GetTotalCount(request), Rows = data }); } }
public async Task <SearchResult <Classifier> > Search(ClassifierSearchRequest request, CancellationToken cancellationToken) { var type = await _classifierTypeService.Get(request.TypeCode, cancellationToken); using (var db = _dbContextFactory.Create()) { var result = await SearchInternal(db, type, request, cancellationToken); // search in data by Uid is not effective - O(n), but ok for small collections if (request.FocusUid.HasValue && result.Rows.Any(x => x.Uid == request.FocusUid) == false) { // todo: add test var focus = await SearchInternal(db, type, new ClassifierSearchRequest { Uid = request.FocusUid, SkipPaging = true }, cancellationToken); for (var i = focus.Rows.Count - 1; i >= 0; i--) { result.Rows.Insert(0, focus.Rows[i]); } } // todo: preload fields for multiple items or (?) store fields in the same table? if (request.IncludeFields) { var metadata = await _metadataService.GetMetadata(type, cancellationToken); foreach (var item in result.Rows) { var fields = await _fieldDataRepository.Search(new FieldDataSearchRequest { Metadata = metadata, EntityTypeCode = Classifier.TypeCode, // ReSharper disable once PossibleInvalidOperationException EntityUids = new[] { item.Uid.Value } }, cancellationToken); item.Fields = fields.Rows.SingleOrDefault(); } } return(result); } }