.net Azure Cosmos SDK: Predicatebuilder for Query in nested collection

37 Views Asked by At

I have a data structure

public record CarMake 
{
    public List<Car> Cars { get; set; }
    public string Id {get;set; }
}

now I want to use a Predicate-Builder to only return those items from an Azure Cosmos DB that fit all the given criteria:

public static IQueryable<CarMake> CarMakeSearch(this IQueryable<CarMake> queryable,
        BaseSearchRequest searchRequest)
{
  Func<Car,bool> predicate = c => true;
  if (searchRequest.MaxPrice > 0) {
     predicate = c => predicate (c) && c.Price <= searchRequest.MaxPrice;
  }
  
  //... a lot more of such conditions
  return queryable.Where(carMake => carMake.Cars.Any(predicate));
}

No matter what I tried (ExpressionBuilders of all kinds with invoke() and without), I keep getting errors from Microsoft.Azure.Cosmos.Client that invoke() is not supported, that it has to be an expression.

What is the suggested way the make such a query on a nested List/Colllection? The collection has to be nested due to the nature of how the data has to be returned. The only workaround I have currently is to initially search with multiple Any() conditions and filter in C# on all at once which isn't very nice (compared to filtering on Database-level).

1

There are 1 best solutions below

1
NotFound On

I don't think there's any way around not using a lambda directly in the filter predicates. As alternative you could just chain all logic together. Maybe not the most elegant solution, but with a lack of better answers it'll at least allow you to implement the logic.

return queryable.Where(carMake => carMake.Cars.Any(c => 
    (maxPrice <= 0 || c.Price <= maxPrice) &&
    (minPrice <= 0 || c.Price >= minPrice)
    )
);