70 votes

LINQ to SQL Where Clause Critères facultatifs

Je travaille avec LINQ to SQL de la requête et ont rencontré un problème lorsque j'ai 4 champs optionnels pour filtrer les données résultat. En option, je veux dire a le choix de saisir une valeur ou non. Plus précisément, quelques zones de texte qui pourrait avoir une valeur ou d'avoir une chaîne vide et quelques listes déroulantes qui aurait pu avoir une valeur sélectionnée ou peut-être pas...

Par exemple:

    using (TagsModelDataContext db = new TagsModelDataContext())
     {
        var query = from tags in db.TagsHeaders
                    where tags.CST.Equals(this.SelectedCust.CustCode.ToUpper()) 
                    && Utility.GetDate(DateTime.Parse(this.txtOrderDateFrom.Text)) <= tags.ORDDTE
                    && Utility.GetDate(DateTime.Parse(this.txtOrderDateTo.Text)) >= tags.ORDDTE
                    select tags;
        this.Results = query.ToADOTable(rec => new object[] { query });
    }

Maintenant, j'ai besoin d'ajouter les champs suivants/les filtres, mais seulement si elles sont fournies par l'utilisateur.

  1. Numéro de produit - Vient à partir d'une autre table qui peut être rejoint à TagsHeaders.
  2. Numéro de commande d'achat - un champ à l'intérieur de la TagsHeaders table.
  3. Numéro de commande - Semblable à la PO #, juste de l'autre colonne.
  4. Statut du produit - Si l'utilisateur a sélectionné ce à partir d'une liste déroulante, le besoin de demander la valeur sélectionnée ici.

La requête j'ai déjà travaille très bien, mais pour compléter la fonction, doivent être en mesure d'ajouter ces 4 autres éléments dans la clause where, juste ne sais pas comment!

121voto

andleer Points 12090

Vous pouvez coder votre requête d'origine:

var query = from tags in db.TagsHeaders
                where tags.CST.Equals(this.SelectedCust.CustCode.ToUpper()) 
                && Utility.GetDate(DateTime.Parse(this.txtOrderDateFrom.Text)) <= tags.ORDDTE
                && Utility.GetDate(DateTime.Parse(this.txtOrderDateTo.Text)) >= tags.ORDDTE
                select tags;

Et puis, sur la base d'une condition, d'ajouter d'autres où les contraintes.

if(condition)
    query = query.Where(i => i.PONumber == "ABC");

Je ne suis pas sûr de savoir comment ce code avec la syntaxe de la requête, mais l'id est le travail avec un lambda. Fonctionne également avec la syntaxe de la requête de la requête initiale et un lambda pour le filtre secondaire.

Vous pouvez également inclure une méthode d'extension (ci-dessous) que j'ai codé un tout qui inclut conditionnelle lorsque les déclarations. (Ne fonctionne pas bien avec la syntaxe de la requête):

        var query = db.TagsHeaders
            .Where(tags => tags.CST.Equals(this.SelectedCust.CustCode.ToUpper()))
            .Where(tags => Utility.GetDate(DateTime.Parse(this.txtOrderDateFrom.Text)) <= tags.ORDDTE)
            .Where(tags => Utility.GetDate(DateTime.Parse(this.txtOrderDateTo.Text)) >= tags.ORDDTE)
            .WhereIf(condition1, tags => tags.PONumber == "ABC")
            .WhereIf(condition2, tags => tags.XYZ > 123);

La méthode d'extension:

public static IQueryable<TSource> WhereIf<TSource>(
    this IQueryable<TSource> source, bool condition,
    Expression<Func<TSource, bool>> predicate)
{
    if (condition)
        return source.Where(predicate);
    else
        return source;
}

Ici est la même méthode d'extension pour IEnumerables:

public static IEnumerable<TSource> WhereIf<TSource>(
    this IEnumerable<TSource> source, bool condition,
    Func<TSource, bool> predicate)
{
    if (condition)
        return source.Where(predicate);
    else
        return source;
}

31voto

Telos Points 3226

Juste besoin d'utiliser une vérification conditionnelle pour l'existence du paramètre. Par exemple:

 where (string.IsNullOrEmpty(ProductNumber) || ProductNumber == tags.productNumber)
 

De cette façon, si le numéro de produit n'est pas entré, cette expression retournera true dans tous les cas, mais si elle est entrée, elle ne retournera que true lors de la mise en correspondance.

0voto

Gregory A Beamer Points 10975

Vous avez la possibilité de OU avec ||.

Découvrez ce fil, car il pourrait vous donner quelques indications utiles: http://stackoverflow.com/questions/403505/c-linq-equivalent-of-a-somewhat-complex-sql-query

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