Reputation: 2632
I have been using the following method pattern in my Web API for searching entities given a set of criteria:
public IEnumerable<Employee> Search(SearchCriteria searchCriteria)
{
var employees = _dbContext.Employees;
if(searchCriteria.Age.HasValue)
{
employees = employees.Where(e => e.Age == searchCriteria.Age.Value);
}
if(searchCriteria...)
{
employees = employees.Where(e => ...);
}
return employees;
}
If a search criterion is not specified, then the property on the SearchCriteria object will be null
and I simply do not filter based on this criterion. If it is specified, then it will have a value, and it is used for filtering.
The problem, from a design perspective, is that if I actually want the employees
that do not have an age, I simply cannot do it this way, since I use null
to determine whether or not I will use the given criterion.
What other approach should I look into in order to emcompass both cases?
Perhaps looking at the URI instead of letting Web API do the object mapping, I could determine whether or not the criterion was actually present?
mysite.com/api/employee?keyword=a&age=null
vs
mysite.com/api/employee?keyword=a
Upvotes: 4
Views: 715
Reputation: 6030
I think you'll have to extend your SearchCriteria
a bit. Instead of Nullable<T>
properties like Nullable<int> Age
you'll need a more detailed structure, that gives you the info, if that criterion should be checked or not.
This might additionally give you the option to not just combine your criterions with logical ANDs but also tweak some more functionality out of it ;)
Upvotes: 2
Reputation: 82277
There is no need to use a conditional check here. If the database value of age can be null, then that means your domain entity must be int?
in which case Age
can be used without .Value
.
public IEnumerable<Employee> Search(SearchCriteria searchCriteria)
{
var employees = _dbContext.Employees.Where(e => e.Age == searchCriteria.Age);
if(searchCriteria...)
{
employees = employees.Where(e => ...);
}
return employees;
}
Upvotes: 0
Reputation: 153
For the filtering the age, maybe you can set the age to -1, for querying employees that do not have an age like:
if(searchCriteria.Age.HasValue){
if(searchCriteria.Age != -1)
employees = employees.Where(e => e.Age == searchCriteria.Age.Value);
}
else{
employees = employees.Where(e => e.Age == null);
}
}
Upvotes: 0