Je travaille avec une requête LINQ to SQL et j'ai rencontré un problème où j'ai 4 champs facultatifs pour filtrer le résultat des données. Par facultatif, je veux dire a le choix d'entrer une valeur ou non. Plus précisément, quelques zones de texte qui pourraient avoir une valeur ou avoir une chaîne vide et quelques listes déroulantes qui auraient 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, je dois ajouter les champs/filtres suivants, mais uniquement s'ils sont fournis par l'utilisateur.
La requête que j'ai déjà fonctionne très bien, mais pour terminer la fonction, vous devez pouvoir ajouter ces 4 autres éléments dans la clause where, je ne sais pas comment!
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, en fonction d'une condition, ajoutez des contraintes Where supplémentaires.
if(condition)
query = query.Where(i => i.PONumber == "ABC");
Je ne sais pas comment coder cela avec la syntaxe de requête, mais id fonctionne avec un lambda. Fonctionne également avec la syntaxe de requête pour 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ée il y a quelque temps pour inclure des instructions conditionnelles where. (Ne fonctionne pas bien avec la syntaxe de 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;
}
Voici 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;
}
Il suffit d'utiliser une vérification conditionnelle de 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 vrai dans tous les cas, mais s'il est entré, il ne retournera vrai que lors de la correspondance.
Vous avez la possibilité de OR avec ||.
Consultez ce fil, car il pourrait vous donner quelques bons pointeurs: équivalent C # LINQ d'une requête SQL quelque peu complexe