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.