Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Unwieldy LINQ statement with multiple search criteria

Tags:

c#

linq

I have a form with multiple search criteria that a user can use to search for employee data, e.g. FirstName, LastName, HireDate, Department, etc.

I am using LINQ and am wondering what method could I use to query a collection of Employes given any of of the search criteria, i.e. a user does not have to enter all, but they do have to enter at least one of the search parameters.

So far, while testing my LINQ statement with two search parameters in place, it seems that I have to see if the search parameter is entered or not. If this is the case, then this can get quite unwieldy for many search parameters.

// only FirstName is entered
if (!string.IsNullOrEmpty(FirstName) && string.IsNullOrEmpty(LastName))
{
    var employees = DB.Employees
        .Where(emp => emp.FirstName.Contains(fName));
}
// only LastName is entered
else if (string.IsNullOrEmpty(FirstName) && !string.IsNullOrEmpty(LastName))
{
    var employees = DB.Employees
        .Where(emp => emp.LastName.Contains(lName));
}
// both parameters are entered
else if (!string.IsNullOrEmpty(FirstName) && !string.IsNullOrEmpty(LastName))
{
    var employees = DB.Employees
        .Where(emp => emp.FirstName.Contains(fName))
        .Where(emp => emp.LastName.Contains(lName));
}

FYI, I initially thought that I could just append Where() statements to my LINQ statement with the pertinent search parameters but I noticed that not all records were being returned that should and thus the above logic of if-then statements.

like image 739
emily_bma Avatar asked Dec 03 '14 22:12

emily_bma


3 Answers

What about something like this:

IQueryable<Employee> employees = DB.Employees;

if (!string.IsNullOrEmpty(FirstName))
{
    employees = employees 
        .Where(emp => emp.FirstName.Contains(fName));
}
if (!string.IsNullOrEmpty(LastName))
{
    employees = employees 
        .Where(emp => emp.Last.Contains(lName));
}
like image 99
thepirat000 Avatar answered Nov 07 '22 18:11

thepirat000


You can write it like this:

var employees = DB.Employees.AsQueryable();
if (!string.IsNullOrEmpty(fName)
  employees = employees.Where(emp => emp.FirstName.Contains(fName));

if (!string.IsNullOrEmpty(lName)
  employees = employees.Where(emp => emp.LastName.Contains(lName));
like image 4
Magnus Avatar answered Nov 07 '22 16:11

Magnus


I encountered a similar challenge where a user could select 0, 1 or many values for about 10 searchable fields and needed to construct that query at runtime.

I ended up using LINQKit: http://www.albahari.com/nutshell/linqkit.aspx

In particular I used it's predicate builder, which is described here: http://www.albahari.com/nutshell/predicatebuilder.aspx

In your example above, you've encompassed the query multiple within if statements. The alternative is to build the query as you go.

If you were to declare var employees = DB.Employees outside of those if statements (Assuming that it's always relevant), then you could just tack on your where statements within your if statements if they're applicable.

LINQ gives you deferred execution, so you don't have to have the entire expression in a single block (Even though it feels most natural to do so and in many cases you will).

Things get a bit more complicated if you want to mix in OR's with ANDs, but that's where the previously mentioned predicate builder comes in.

Unfortunately I don't have any examples to share, but those links should get you off to a good start.

like image 1
Steviebob Avatar answered Nov 07 '22 16:11

Steviebob