Dynamically filtering content on hierarchical categories
Our solution calls for a number of dynamic content items with a hierarchical category field containing any number of taxons.
The hierarchical structure is separated into n category groups. For example: Size Large, Medium, Small and Color Red Green Blue .
The UI allows a user to select any number of these to filter the content. eg. Large + Red + Green should return anything Large & Red or Large & Green. The selected taxons are returned to the server as a 2D array of Guids (the above selection would be [[Large], [Red, Green]]).
I have been able to filter by a single filter group, but when I try to add a second filter group no results are returned even though I have content that should fit the criteria. My code is:
[HttpPost][RelativeRoute("GetProducts")]public JsonResult GetProducts(ProductListRequest request) var products = GetProducts(); products = FilterProducts(products, request); var response = new ProductListResponse(request.Page, ProductsPerPage); response.AllProductsCount = products.Count(); if (request.Page >= 0) products = products.Skip(request.Page * ProductsPerPage).Take(ProductsPerPage); response.Products = products; return Json(response);public static IQueryable<DynamicContent> GetProducts() DynamicModuleManager dynamicModuleManager = DynamicModuleManager.GetManager("OpenAccessProvider"); Type productType = TypeResolutionService.ResolveType("Telerik.Sitefinity.DynamicTypes.Model.MyModule.Product"); return dynamicModuleManager.GetDataItems(productType).Where(p => p.Status == ContentLifecycleStatus.Live);public static IQueryable<DynamicContent> FilterProducts(IQueryable<DynamicContent> products, ProductListRequest request) if (request.FilterList == null) return products; foreach (Guid[] filterlist in request.FilterList.Where(x => x != null)) products = FilterByCategory(products, filterlist); return products;private static IQueryable<DynamicContent> FilterByCategory(IQueryable<DynamicContent> products, Guid[] categories) if (categories.Any()) products = products.Where(p => p.GetValue<TrackedList<Guid>>("Category").Any(g => categories.Contains(g))); return products;
Here is an example of a filter against 2 taxon groups which returns no results:
Extent<Telerik.Sitefinity.DynamicTypes.Model.MyModel.Product>().Where(re-p => (re-p.ApplicationName == OpenAccessProvider.ApplicationName)).Where(re-p => (Convert(Convert(Convert(Convert(Convert(Convert(Convert(re-p.Status))))))) == 2)).Where(re-p => re-p.FieldValue("Category").Any(g => value(SitefinityWebApp.MyApp.Products+<>c__DisplayClass3_0).categories.Contains(g))).Where(re-p => re-p.FieldValue("Category").Any(g => value(SitefinityWebApp.MyApp.Products+<>c__DisplayClass3_0).categories.Contains(g)))
Please help me understand why this is not working.
Just an update. I have found that using the IEnumerable.Where() works, but the IQueryable.Where() does not. I am guessing this is a result of deferred execution, trying to mix the IEnumerable Guid[] with the IQueryable content collection.
I am not keen on the idea of resolving the IQueryable to an IEnumerable to get this to work, so I would be interested to learn if anybody has solved this in any other ways.