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.
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.
精彩评论