wake-up-neo.com

LINQ to SQL Where-Klausel Optionale Kriterien

Ich arbeite mit einer LINQ to SQL-Abfrage und bin auf ein Problem gestoßen, bei dem ich 4 optionale Felder zum Filtern des Datenergebnisses habe. Mit optional meine ich, hat die Wahl, einen Wert einzugeben oder nicht. Insbesondere einige Textfelder, in denen ein Wert oder eine leere Zeichenfolge enthalten sein könnte, und einige Dropdown-Listen, in denen ein Wert ausgewählt sein könnte oder nicht ...

Beispielsweise:

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

Jetzt muss ich die folgenden Felder/Filter hinzufügen, aber nur, wenn sie vom Benutzer bereitgestellt werden.

  1. Produktnummer - stammt aus einer anderen Tabelle, die mit TagsHeaders verknüpft werden kann.
  2. Bestellnummer - Ein Feld in der Tabelle TagsHeaders.
  3. Bestellnummer - Ähnlich wie bei der Bestellnummer, nur in einer anderen Spalte.
  4. Produktstatus - Wenn der Benutzer dies aus einer Dropdown-Liste ausgewählt hat, muss der ausgewählte Wert hier angewendet werden.

Die Abfrage, die ich bereits habe, funktioniert prima, aber um die Funktion zu vervollständigen, müssen Sie in der Lage sein, diese 4 anderen Elemente in die where-Klausel einzufügen. Sie wissen nur nicht, wie!

70
RSolberg

Sie können Ihre ursprüngliche Abfrage codieren:

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;

Fügen Sie dann basierend auf einer Bedingung weitere where-Einschränkungen hinzu.

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

Ich bin nicht sicher, wie ich das mit der Abfragesyntax codieren soll, aber id funktioniert mit einem Lambda. Funktioniert auch mit der Abfragesyntax für die erste Abfrage und einem Lambda für den sekundären Filter.

Sie können auch eine Erweiterungsmethode (siehe unten) einfügen, die ich vor einiger Zeit so programmiert habe, dass sie bedingte where-Anweisungen enthält. (Funktioniert nicht gut mit der Abfragesyntax):

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

Die Erweiterungsmethode:

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

Hier ist die gleiche Erweiterungsmethode für 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;
}
120
andleer

Es muss nur eine bedingte Prüfung für die Existenz des Parameters verwendet werden. Zum Beispiel:

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

Wenn die Produktnummer nicht eingegeben wird, gibt dieser Ausdruck in allen Fällen true zurück. Wenn er jedoch eingegeben wird, wird nur true zurückgegeben, wenn eine Übereinstimmung vorliegt.

31
CodeRedick

Sie haben die Möglichkeit, OR mit ||.

Schauen Sie sich diesen Thread an, da er Ihnen einige nette Hinweise geben könnte: C # LINQ-Äquivalent einer etwas komplexen SQL-Abfrage

0