public async Task <FileCountResult> CountFilesGroupedAsync(MediaFilesFilter filter) { Guard.NotNull(filter, nameof(filter)); // Base db query var q = _searcher.ApplyFilterQuery(filter); // Get ids of untrackable folders, 'cause no orphan check can be made for them. var untrackableFolderIds = _folderService.GetRootNode() .SelectNodes(x => !x.Value.CanDetectTracks) .Select(x => x.Value.Id) .ToArray(); // Determine counts var result = await(from f in q group f by 1 into g select new FileCountResult { Total = g.Count(), Trash = g.Count(x => x.Deleted), Unassigned = g.Count(x => !x.Deleted && x.FolderId == null), Transient = g.Count(x => !x.Deleted && x.IsTransient == true), Orphan = g.Count(x => !x.Deleted && x.FolderId > 0 && !untrackableFolderIds.Contains(x.FolderId.Value) && !x.Tracks.Any()) }).FirstOrDefaultAsync() ?? new FileCountResult(); if (result.Total == 0) { result.Folders = new Dictionary <int, int>(); return(result); } // Determine file count for each folder var byFolders = from f in q where f.FolderId > 0 && !f.Deleted group f by f.FolderId.Value into grp select grp; result.Folders = await byFolders .Select(grp => new { FolderId = grp.Key, Count = grp.Count() }) .ToDictionaryAsync(k => k.FolderId, v => v.Count); result.Filter = filter; return(result); }
public virtual IQueryable <MediaFile> ApplyFilterQuery(MediaFilesFilter filter, IQueryable <MediaFile> sourceQuery = null) { Guard.NotNull(filter, nameof(filter)); var q = sourceQuery ?? _db.MediaFiles.AsQueryable(); // Term if (filter.Term.HasValue() && filter.Term != "*") { // Convert file pattern to SQL 'LIKE' expression q = ApplySearchTerm(q, filter.Term, filter.IncludeAltForTerm, filter.ExactMatch); } // MediaType if (filter.MediaTypes != null && filter.MediaTypes.Length > 0) { if (filter.MediaTypes.Length == 1) { var right = filter.MediaTypes[0]; q = q.Where(x => x.MediaType == right); } else if (filter.MediaTypes.Length > 1) { q = q.Where(x => filter.MediaTypes.Contains(x.MediaType)); } else { // (perf) Composite index q = q.Where(x => !string.IsNullOrEmpty(x.MediaType)); } } // Extension if (filter.Extensions != null && filter.Extensions.Length > 0) { if (filter.Extensions.Length == 1) { var right = filter.Extensions[0]; q = q.Where(x => x.Extension == right); } else if (filter.Extensions.Length > 1) { q = q.Where(x => filter.Extensions.Contains(x.Extension)); } else { // (perf) Composite index q = q.Where(x => !string.IsNullOrEmpty(x.Extension)); } } // Tags if (filter.Tags != null && filter.Tags.Length > 0) { q = q.Where(x => x.Tags.Any(t => filter.Tags.Contains(t.Id))); } // Image dimension if (filter.Dimensions != null && filter.Dimensions.Length > 0) { var predicates = new List <Expression <Func <MediaFile, bool> > >(5); foreach (var dim in filter.Dimensions.OrderBy(x => x).Distinct()) { if (dim == ImageDimension.VerySmall) { predicates.Add(x => x.PixelSize > 0 && x.PixelSize <= 50000); } else if (dim == ImageDimension.Small) { predicates.Add(x => x.PixelSize > 50000 && x.PixelSize <= 250000); } else if (dim == ImageDimension.Medium) { predicates.Add(x => x.PixelSize > 250000 && x.PixelSize <= 1000000); } else if (dim == ImageDimension.Large) { predicates.Add(x => x.PixelSize > 1000000 && x.PixelSize <= 2000000); } else if (dim == ImageDimension.VeryLarge) { predicates.Add(x => x.PixelSize > 2000000); } } if (predicates.Any()) { var predicate = PredicateBuilder.New(predicates.First()); for (var i = 1; i < predicates.Count; i++) { predicate = PredicateBuilder.Or(predicate, predicates[i]); } q = q.Where(predicate); } } // Deleted if (filter.Deleted != null) { q = q.Where(x => x.Deleted == filter.Deleted.Value); } #region Currently unindexed // MimeType if (filter.MimeTypes != null && filter.MimeTypes.Length > 0) { if (filter.MimeTypes.Length == 1) { var right = filter.MimeTypes[0]; q = q.Where(x => x.MimeType == right); } else if (filter.MimeTypes.Length > 1) { q = q.Where(x => filter.MimeTypes.Contains(x.MimeType)); } } // Hidden if (filter.Hidden != null) { q = q.Where(x => x.Hidden == filter.Hidden.Value); } #endregion return(q); }