/// <summary> /// Search in multiple data sources. /// </summary> /// <param name="criteria"></param> /// <returns></returns> public MembersSearchResult SearchMembers(MembersSearchCriteria criteria) { var retVal = new MembersSearchResult(); var skip = criteria.Skip; var take = criteria.Take; var memberTypes = criteria.MemberTypes; /// !!!Ahtung!!!: Because members can be searched in multiple data sources we have to always use sorting by memberType field (asc or desc) /// instead pagination will not works properly var sortByMemberType = criteria.SortInfos.FirstOrDefault(x => string.Equals(x.SortColumn, "memberType", StringComparison.OrdinalIgnoreCase)) ?? new SortInfo { SortColumn = "memberType" }; var sortInfos = criteria.SortInfos.Where(x => x != sortByMemberType); criteria.Sort = SortInfo.ToString(new[] { sortByMemberType }.Concat(sortInfos)); foreach (var memberMapping in _memberMappings) { criteria.MemberTypes = memberTypes.IsNullOrEmpty() ? memberMapping.AllSupportedMemberTypeNames.ToArray() : memberMapping.AllSupportedMemberTypeNames.Intersect(memberTypes, StringComparer.OrdinalIgnoreCase).ToArray(); if (!criteria.MemberTypes.IsNullOrEmpty() && criteria.Take >= 0) { var result = memberMapping.MemberSearchService.SearchMembers(criteria); retVal.Members.AddRange(result.Members); retVal.TotalCount += result.TotalCount; criteria.Skip = Math.Max(0, skip - retVal.TotalCount); criteria.Take = Math.Max(0, take - result.Members.Count()); } } //restore back criteria property values criteria.Skip = skip; criteria.Take = take; criteria.MemberTypes = memberTypes; return(retVal); }
/// <summary> /// Search members in database by given criteria /// </summary> /// <param name="criteria"></param> /// <returns></returns> public virtual MembersSearchResult SearchMembers(MembersSearchCriteria criteria) { var retVal = new MembersSearchResult(); using (var repository = RepositoryFactory()) { var query = LinqKit.Extensions.AsExpandable(repository.Members); if (!criteria.MemberTypes.IsNullOrEmpty()) { query = query.Where(x => criteria.MemberTypes.Contains(x.MemberType) || x.MemberType == null); } if (criteria.MemberId != null) { //TODO: DeepSearch in specified member query = query.Where(x => x.MemberRelations.Any(y => y.AncestorId == criteria.MemberId)); } else { if (!criteria.DeepSearch) { query = query.Where(x => !x.MemberRelations.Any()); } } //Get extra predicates (where clause) var predicate = GetQueryPredicate(criteria); query = query.Where(LinqKit.Extensions.Expand(predicate)); var sortInfos = criteria.SortInfos; if (sortInfos.IsNullOrEmpty()) { sortInfos = new[] { new SortInfo { SortColumn = ReflectionUtility.GetPropertyName <Member>(x => x.MemberType), SortDirection = SortDirection.Descending } }; } query = query.OrderBySortInfos(sortInfos); retVal.TotalCount = query.Count(); retVal.Members = query.Skip(criteria.Skip).Take(criteria.Take).ToArray() .Select(x => x.ToMember(MemberFactory.TryCreateMember(x.MemberType))).ToList(); return(retVal); } }