public SearchInformation Query( [FromBody] SearchRequest request ) { // Default if (request == null) request = new SearchRequest(); // Prepare request.Validate(); // Create response var response = new SearchInformation { PageIndex = request.PageIndex, PageSize = request.PageSize }; // Root query var recordings = Database .Apply( request, response ) .Include( r => r.Languages ) .Include( r => r.Genres ); // Time to execute response.Recordings = recordings.Select( RecordingForTable.Create ).ToArray(); // Report return response; }
/// <summary> /// Wendet die Suchbeschreibung auf eine Suche an. /// </summary> /// <param name="database">Die zu verwendende Datenbank.</param> /// <param name="request">Die gewümschten Einschränkungen.</param> /// <param name="response">Das Ergebnis der Suche.</param> /// <returns>Die vorbereitete Suche.</returns> public static IQueryable<Models.Recording> Apply( this DAL.Database database, SearchRequest request, SearchInformation response ) { var recordings = (IQueryable<Models.Recording>) database.Recordings; // Apply genre filter if (request.RequiredGenres.Count > 0) recordings = recordings.Where( r => request.RequiredGenres.All( g => r.Genres.Any( rg => rg.UniqueIdentifier == g ) ) ); // Apply series if (request.AllowedSeries.Count > 0) recordings = recordings.Where( r => request.AllowedSeries.Contains( r.SeriesIdentifier.Value ) ); // Apply rent option if (request.IsRent.HasValue) recordings = recordings.Where( r => request.IsRent.Value == (r.RentTo != null) ); // Free text if (!string.IsNullOrEmpty( request.Text )) recordings = recordings.Where( r => r.FullName.Contains( request.Text ) ); // Language statistics is made just prior to setting the language because currently only one language may be choosen if (response != null) response.LanguageStatistics = recordings .SelectMany( r => r.Languages ) .GroupBy( l => l.UniqueIdentifier ) .Select( g => new SearchInformation.Language { Identifier = g.Key, Count = g.Count() } ) .ToArray(); // Apply language filter if (request.RequiredLanguage.HasValue) recordings = recordings.Where( r => r.Languages.Any( l => l.UniqueIdentifier == request.RequiredLanguage.Value ) ); // Check counter after filter is applied but bevore we start restricting if (response != null) response.TotalCount = recordings.Count(); // Genre statistics will be made on full restriction to support multi value if (response != null) response.GenreStatistics = recordings .SelectMany( r => r.Genres ) .GroupBy( g => g.UniqueIdentifier ) .Select( g => new SearchInformation.Genre { Identifier = g.Key, Count = g.Count() } ) .ToArray(); // Apply order switch (request.OrderBy) { case SearchRequestOrderBy.HierarchicalName: if (request.SortAscending) recordings = recordings.OrderBy( recording => recording.FullName ); else recordings = recordings.OrderByDescending( recording => recording.FullName ); break; case SearchRequestOrderBy.Created: if (request.SortAscending) recordings = recordings.OrderBy( recording => recording.CreationTimeInDatabase ); else recordings = recordings.OrderByDescending( recording => recording.CreationTimeInDatabase ); break; } // Done if (response == null) return recordings; // Apply start offset var offset = request.Offset; if (offset > 0) recordings = recordings.Skip( offset ); // Always restrict number of results return recordings.Take( request.PageSize ); }