Linq: adding conditions to the where clause conditionally
one option.
bool? age = null
(from u in DataContext.Users
where u.Division == strUserDiv
&& (age == null || (age != null && u.Age > age.Value))
&& u.Height > strHeightinFeet
select new DTO_UserMaster
{
Prop1 = u.Name,
}).ToList();
or you could switch to the method syntax for linq and use if conditions to attach expressions to the where clause.
Simply I am using it in my where clause as
public IList<ent_para> getList(ent_para para){
db.table1.Where(w=>(para.abc!=""?w.para==para.abc:true==true) && (para.xyz!=""?w.xyz==para.xyz:true==true)).ToList();
}
I usually use method chaining but have the same problem. And here is extension I use
public static IQueryable<T> ConditionalWhere<T>(
this IQueryable<T> source,
Func<bool> condition,
Expression<Func<T, bool>> predicate)
{
if (condition())
{
return source.Where(predicate);
}
return source;
}
It helps to avoid chain breaks. Also the same ConditionalOrderBy
and ConditionalOrderByDescending
are helpful.
If you do not call ToList()
and your final mapping to the DTO type, you can add Where
clauses as you go, and build the results at the end:
var query = from u in DataContext.Users
where u.Division == strUserDiv
&& u.Age > 18
&& u.Height > strHeightinFeet
select u;
if (useAge)
query = query.Where(u => u.Age > age);
if (useHeight)
query = query.Where(u => u.Height > strHeightinFeet);
// Build the results at the end
var results = query.Select(u => new DTO_UserMaster
{
Prop1 = u.Name,
}).ToList();
This will still only result in a single call to the database, which will be effectively just as efficient as writing the query in one pass.