web-dev-qa-db-fra.com

Linq: ajout de conditions à la clause where sous condition

J'ai une requête comme celle-ci

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

Je souhaite ajouter différentes conditions, telles que l'âge et la hauteur, selon que ces conditions ont été fournies ou non à la méthode qui exécute cette requête. Toutes les conditions incluront la division utilisateur. Si age a été fourni, je veux ajouter cela à la requête. De même, si la hauteur était fournie, je veux ajouter cela aussi.

Si cela devait être fait en utilisant des requêtes SQL, j'aurais utilisé le constructeur de chaînes pour les ajouter à la requête principale strSQL. Mais ici, à Linq, je ne peux penser qu’à utiliser une condition IF dans laquelle je vais écrire trois fois la même requête, chaque bloc IF ayant une condition supplémentaire. Y a-t-il une meilleure manière de faire cela?

Merci pour votre temps..

86
user20358

Si vous n'appelez pas ToList() et votre correspondance finale avec le type DTO, vous pouvez ajouter des clauses Where au fur et à mesure et générer les résultats à la fin:

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

Cela n'entraînera toujours qu'un seul appel à la base de données, ce qui sera tout aussi efficace que d'écrire la requête en une seule passe.

149
Reed Copsey

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

vous pouvez également passer à la syntaxe de la méthode linq et utiliser les conditions if pour associer des expressions à la clause where.

15
Matthew Vines

J'utilise habituellement la méthode de chaînage mais j'ai le même problème. Et voici l'extension que j'utilise

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

Cela aide à éviter les ruptures de chaîne. Les mêmes ConditionalOrderBy et ConditionalOrderByDescending sont également utiles.

11
Yuriy Granovskiy

Simplement je l'utilise dans ma clause 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();
}
3
Own

Voici mon code pour faire la même chose. Ceci est une méthode sur mon WCF SOAP api de service Web.

    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 requête de base est Select(f => f), ce qui signifie fondamentalement TOUT, et les clauses Where lui sont éventuellement rattachées. Le dernier Select est optionnel. J'utilise pour convertir les objets de lignes de base de données en objets de résultat "Fruit".

3
John Henckel

En fonction de certaines conditions, ajoutez la condition 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();
2
Melu

En supposant que le paramètre suivant,

Int? Age = 18;

En utilisant simplement && et || opérateurs conditionnels, nous pouvons avoir une autre version. Ici.

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

Comme Param1, vous pouvez ajouter un nombre quelconque de paramètres pour la condition de recherche.

0
Sushant yelpale