I am wondering whether I can simplify my code below, especially the following 2 statements:
// Statement A
Expression<Func<Product, bool>>? criteria = p =>
(id == null ? true : p.Id == id) &&
(name == null ? true : p.Name.ToLower().Contains(name.ToLower())) &&
(maxPrice == null ? true : p.Price <= maxPrice);
// Statement B
if (id is null && name is null && maxPrice is null)
criteria = null;
I am not happy with the statement B because of two reasons:
The following does not compile because
An expression tree cannot contain an assignment operator.
bool sign = false;
Criteria = p =>
(id == null ? (sign = true) : p.Id == id) &&
(name == null ? (sign = true) : p.Name.ToLower().Contains(name.ToLower()))
;
if (sign == false)
Criteria = null;
Is there any way to make it much simpler and less prone to errors? Any suggestions are always welcome.
static IQueryable<Product> Filter(this IQueryable<Product> products,
int? id = null,
string? name = null,
decimal? maxPrice = null)
{
Expression<Func<Product, bool>>? criteria = p =>
(id == null ? true : p.Id == id) &&
(name == null ? true : p.Name.ToLower().Contains(name.ToLower())) &&
(maxPrice == null ? true : p.Price <= maxPrice);
if (id is null && name is null && maxPrice is null)
criteria = null;
if (criteria is null)
return products;
else
return products.Where(criteria);
}
Just follow the pretty standard pattern of dynamically adding Where
based on presence of filtering conditions:
static IQueryable<Product> Filter(this IQueryable<Product> products,
int? id = null,
string? name = null,
decimal? maxPrice = null)
{
if (id is not null)
{
products = products.Where(p => p.Id == id);
}
if (name is not null)
{
products = products.Where(p => p.Name.ToLower().Contains(name.ToLower()));
}
if (maxPrice is not null)
{
products = products.Where(p => p.Price <= maxPrice);
}
return products;
}