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; }
这有助于避免断链。 ConditionalOrderBy
和ConditionalOrderByDescending
也是有帮助的。
这是我的代码做类似的事情。 这是我的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();