Linq: agregar condiciones a la cláusula where condicionalmente

Tengo una consulta como esta

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

Deseo agregar las diversas condiciones, como la edad y la altura, según si esas condiciones se proporcionaron al método que ejecuta esta consulta. Todas las condiciones incluirán la división de usuario. Si se proporcionó la edad, quiero agregar eso a la consulta. De manera similar, si se proporcionó altura, también quiero agregar eso.

Si esto se hiciera usando consultas sql, habría utilizado el generador de cadenas para adjuntarlas a la consulta strSQL principal. Pero aquí en Linq solo puedo pensar en usar una condición IF donde escribiré la misma consulta tres veces, con cada bloque IF teniendo una condición adicional. ¿Hay una mejor manera de hacer esto?

Gracias por tu tiempo..

Si no llama a ToList() y su asignación final al tipo de DTO, puede agregar cláusulas Where medida que ToList() y generar los resultados al final:

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

Esto solo dará como resultado una sola llamada a la base de datos, que será efectivamente tan eficiente como escribir la consulta en una sola pasada.

una opción.

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

o puede cambiar a la syntax del método para linq y usar si las condiciones para adjuntar expresiones a la cláusula where.

Usualmente uso el método de encadenamiento pero tengo el mismo problema. Y aquí está la extensión que uso

 public static IQueryable ConditionalWhere( this IQueryable source, Func condition, Expression> predicate) { if (condition()) { return source.Where(predicate); } return source; } 

Ayuda a evitar los cortes de cadena. También el mismo ConditionalOrderBy y ConditionalOrderByDescending son útiles.

Aquí está mi código para hacer algo similar. Este es un método en mi aplicación WCF SOAP Web Service.

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

La consulta base es Select(f => f) que básicamente significa TODO, y las cláusulas Where están opcionalmente unidas a él. La selección final es opcional. Utilizo para convertir los objetos de las filas de la base de datos en objetos resultantes “Frutas”.

Simplemente lo estoy usando en mi cláusula where

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

En función de cierta condición, agregue la condición where …

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