Linq:有条件地给where子句添加条件

我有这样的查询

(from u in DataContext.Users where u.Division == strUserDiv && u.Age > 18 && u.Height > strHeightinFeet select new DTO_UserMaster { Prop1 = u.Name, }).ToList(); 

我想根据这些条件是否提供给运行此查询的方法来添加各种条件,如年龄,身高。 所有条件将包括用户司。 如果年龄提供,我想添加到查询。 相似,如果提供了高度,我想补充一点。

如果这是使用sql查询完成的,我会使用string生成器将它们追加到主strSQL查询中。 但是在Linq中,我只能想到使用一个IF条件,在这个条件下,我将三次写入相同的查询,每个IF块都有一个额外的条件。 有一个更好的方法吗?

谢谢你的时间..

如果您不调用ToList()和最终映射到DTOtypes,则可以随时添加Where子句,并在结尾处生成结果:

 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(); 

这仍然只会导致对数据库的单一调用,这将与一次写入查询的效率一样高效。

一个选项。

 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(); 

或者你可以切换到linq的方法语法,并使用条件来附加expression式的where子句。

我通常使用方法链接,但也有同样的问题。 这里是我使用的扩展

 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; } 

这有助于避免断链。 ConditionalOrderByConditionalOrderByDescending也是有帮助的。

这是我的代码做类似的事情。 这是我的WCF SOAP Web服务api上的一个方法。

  public FruitListResponse GetFruits(string color, bool? ripe) { try { FruitContext db = new FruitContext(); var query = db.Fruits.Select(f => f); if (color != null) { query = query.Where(f => f.Color == color); } if (ripe != null) { query = query.Where(f => f.Ripe == ripe); } return new FruitListResponse { Result = query.Select(f => new Fruit { Id = f.FruitId, Name = f.Name }).ToList() }; } catch (Exception e) { return new FruitListResponse { ErrorMessage = e.Message }; } } 

基本查询是Select(f => f) ,这意味着基本上所有事情,并且Where子句可选地附加到它。 最终的Select是可选的。 我使用将数据库行对象转换为结果“水果”对象。

只是我在我的where子句中使用它

  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(); } 

基于某些条件,添加条件…

 from u in DataContext.Users where u.Division == strUserDiv && u.Age != null ? u.Age > 18 : 1== 1 && u.Height != null ? u.Height > 18 : 1== 1 && u.Height != null ? u.Height > 18 : 1== 1 select new DTO_UserMaster { Prop1 = u.Name, }).ToList();