146 votes

Linq : ajouter des conditions à la clause where de manière conditionnelle

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 les différentes conditions telles que l'âge, la taille en fonction des conditions fournies à la méthode qui exécute cette requête. Toutes les conditions incluront la division de l'utilisateur. Si l'âge a été fourni, je veux l'ajouter à la requête. De même, si la taille a été fournie, je veux l'ajouter également.

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, en Linq, je ne peux que penser à utiliser une condition IF où j'écrirais la même requête trois fois, avec chaque bloc IF ayant une condition supplémentaire. Existe-t-il une meilleure façon de procéder ?

5voto

John Henckel Points 554

Voici mon code pour faire la même chose. Il s'agit d'une méthode de mon api 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 requête de base est Select(f => f) ce qui veut dire en gros TOUT, et la Where lui sont éventuellement associées. La clause Select est facultatif. Je l'utilise pour convertir les objets lignes de la base de données en objets résultats "Fruit".

3voto

Riaan Saayman Points 66

Pour compléter la réponse acceptée ci-dessus aquí , si vous effectuez une recherche dynamique sur une jointure, pensez à renvoyer un nouvel objet avec les deux tables (t1,t2) dans la requête linq initiale afin de pouvoir y accéder individuellement pour effectuer la recherche conditionnelle.

var query = from t1 in _context.Table1
            join t2 in _context.Table2 on t1.Table1Id equals t2.Table1IdId
            select new { t1, t2 };

        if (!string.IsNullOrEmpty(searchProperty1))
        {
            query = query.Where(collection => collection.t1.TableColumn == searchProperty1);
        }
        if (!string.IsNullOrEmpty(searchProperty2))
        {
            query = query.Where(collection => collection.t2.TableColumn == searchProperty2);
        }
        ....etc.

J'ai obtenu la réponse que je cherchais aquí en ce qui concerne la jonction de deux tables et l'interrogation de colonnes spécifiques sur l'une ou l'autre des tables

1voto

Scott Peterson Points 63

Je suis tombé sur ce document en cherchant autre chose, mais j'ai pensé ajouter la version lambda.

Tout d'abord, je créerais une classe comme celle-ci pour passer des paramètres dans une couche de données :

   public class SearchParameters() {
       public int? Age {get; set;}
       public string Division {get;set;}
       etc
    }

Ensuite, dans ma couche de données, quelque chose comme ceci :

public IQueryable<User> SearchUsers(SearchParameters params) 
{
    var query = Context.Users;
    if (params.Age.HasValue)
    {
         query = query.Where(u => u.Age == params.Age.Value);
    }
    if (!string.IsNullOrEmpty(params.Division)
    {
        query = query.Where(u => u.Division == params.Division);
    }
    etc
    return query;
}

L'endroit où vous concrétisez la demande vous appartient. Il peut y avoir une couche entre l'application et les données qui convertit les représentations spécifiques à la base de données en représentations agnostiques à la base de données (vous interrogez peut-être plusieurs sources de données). Cette couche peut obtenir plusieurs types de données à partir de ces sources et les convertir en une représentation POCO commune, par exemple.

0voto

Sushant Yelpale Points 711

En supposant le paramètre suivant,

Int? Age = 18;

Il suffit d'utiliser && y || les opérateurs conditionnels, nous pouvons avoir une autre version.

(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 pour Param1, vous pouvez ajouter un nombre illimité de paramètres pour la condition de recherche.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X