Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Using conditionals in Linq Programmatically

I was just reading a recent question on using conditionals in Linq and it reminded me of an issue I have not been able to resolve. When building Linq to SQL queries programmatically how can this be done when the number of conditionals is not known until runtime?

For instance in the code below the first clause creates an IQueryable that, if executed, would select all the tasks (called issues) in the database, the 2nd clause will refine that to just issues assigned to one department if one has been selected in a combobox (Which has it's selected item bound to the departmentToShow property).

How could I do this using the selectedItems collection instead?

IQueryable<Issue> issuesQuery;

// Will select all tasks
issuesQuery = from i in db.Issues
              orderby i.IssDueDate, i.IssUrgency
              select i;

// Filters out all other Departments if one is selected
   if (departmentToShow != "All")
   {
        issuesQuery = from i in issuesQuery
                      where i.IssDepartment == departmentToShow
                      select i;
    }

By the way, the above code is simplified, in the actual code there are about a dozen clauses that refine the query based on the users search and filter settings.

like image 382
Mike B Avatar asked Mar 13 '10 17:03

Mike B


1 Answers

If the number of conditions is unknown then it's easier to use lambda syntax instead of query comprehension, i.e.:

IQueryable<Issue> issues = db.Issues;
if (departmentToShow != "All")
{
    issues = issues.Where(i => i.IssDepartment == departmentToShow);
}
issues = issues.OrderBy(i => i.IssDueDate).ThenBy(i => i.IssUrgency);

(Assuming you want the ordering to happen after the filtering, which ought to be the case - I'm not sure if Linq will generate an optimized query if you try to do the ordering first).

If you've got a very large number of optional conditions then you can clean it up with predicates:

List<Predicate<Issue>> conditions = new List<Predicate<Issue>>();
if (departmentToShow != "All")
    conditions.Add(i => i.IssDepartment == departmentToShow);
if (someOtherThing)
    conditions.Add(anotherPredicate);
// etc. snip adding conditions

var issues = from i in issues
             where conditions.All(c => c(i))
             orderby i.IssDueDate, i.IssUrgency;

Or just use PredicateBuilder which is probably easier.

like image 57
Aaronaught Avatar answered Sep 30 '22 17:09

Aaronaught