When there are multiple query conditions at the same time and do not know whether each query condition has a value, we must first determine whether the condition is empty, and then determine whether to add it to the filter condition, using Where is more troublesome, whether Provide a WhereIf extension similar to Abp, that is very convenient, this is just a request for optimization, thank you.
db.Employee
.WhereIf<Employee>(!string.IsNullOrEmpty(query.key), n => n.Name == query.key || n.Description.Contains(query.key)).ToList();
Hey @Uchiha-Peng
I can see how this can be helpful. I would actually not introduce a new term for that, instead just overload the Where extension.
Example usage:
public class CustomerSpec : Specification<Customer>
// Instead of having this
public CustomerSpec(CustomerFilter filter)
if (!string.IsNullOrEmpty(filter.Name))
Query.Where(x => x.Name == filter.Name);
if (!string.IsNullOrEmpty(filter.Email))
Query.Where(x => x.Email == filter.Email);
if (!string.IsNullOrEmpty(filter.Address))
Query.Search(x => x.Address, "%" + filter.Address + "%");
// Users can do this
public CustomerSpec(CustomerFilter filter)
Query
.Where(x => x.Name == filter.Name, condition: !string.IsNullOrEmpty(filter.Name))
.Where(x => x.Email == filter.Email, condition: !string.IsNullOrEmpty(filter.Email))
.Search(x => x.Address, "%" + filter.Address + "%", condition: !string.IsNullOrEmpty(filter.Address));
You can do it even now, you just need to add the following extension in your projects. We tried to make the infrastructure quite extensible (even though I'm still not happy with it).
using System;
using System.Collections.Generic;
using System.Linq.Expressions;
// Keep the same namespace, so it can be discovered automatically
namespace Ardalis.Specification
public static class MySpecificationBuilderExtensions
public static ISpecificationBuilder<T> Where<T>(
this ISpecificationBuilder<T> specificationBuilder,
Expression<Func<T, bool>> criteria,
bool condition)
if (condition)
((List<Expression<Func<T, bool>>>)specificationBuilder.Specification.WhereExpressions).Add(criteria);
return specificationBuilder;
@ardalis any thoughts? We need some more feedback from users if this is something they want, and perhaps include it OOTB. I see @MisinformedDNA disliked this one :)
I later thought about it carefully, in fact, there is no need to expand, just use the ternary operator, which is what I do now
Query
.Where(n => string.IsNullOrWhiteSpace(query.KeyWoard) ? true : (
n.Name.Contains(query.KeyWoard) ||
n.Phone.Contains(query.KeyWoard) ||
n.Remark.Contains(query.KeyWoard) ||
n.Address.Contains(query.KeyWoard))
).Where(n => (query.Gender.HasValue ? n.Gender == query.Gender.Value : true));
Would be really nice if the overload method mentioned by @fiseni gets implemented in the future release. On one hand, if we need general query for an entity collection and then do some filter on it if some keyword exists then this would be very convenient. Otherwise if we need to query for some other specific criteria for indexing and caching we can always make a more specific Specification without any conditions.