Gabriel G. Roy
Gabriel G. Roy

Reputation: 2632

Search criteria and NULL

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

Answers (3)

Jan K&#246;hler
Jan K&#246;hler

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

Travis J
Travis J

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

knightRider
knightRider

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

Related Questions