C # linq - Ändere das ausgewählte Feld zur Laufzeit

c# dynamic expression-trees linq

Frage

Ich habe ein Objekt Bestellungen (Bestellung, Produkt, Kosten, Preis, Kunde, Tag). Ich lade viele Datensätze aus der Datenbank ab und um die Filterung zu erleichtern, muss ich DropDownLists mit den eindeutigen Werten verknüpfen, damit der Benutzer nur bestimmte Daten oder bestimmte Produkte oder sogar einen bestimmten Preis auswählen kann. Die IDs der DropDownList werden als "ddl_" + Name des betroffenen Feldes erstellt.

Ich möchte ein einfaches Array wie dieses definieren können:

public string[] filterArray = new string[] { "Order", "Product", "Cost", "Price", "Client", "Day" };

Rufen Sie dann eine BindDLLs-Methode auf:

foreach (string filterName in filterArray)
{
    // Find the ddl to populate
    DropDownList ddl = (DropDownList)this.FindControl("ddl_" + filterName);
    // Get the data for that ddl only (use filterName in the select...)
    var query = (from items in results select items.filterName.ToString()).Distinct();

    // Populate the ddl (not complete code...)
    foreach (var item in query)
    {
        ddl.Items.Add(item...);
    }
}

Mein Problem ist, dass ich viel Dokumentation darüber finde, wie man die WHERE oder GROUP BY oder andere Teile von linq Anweisungen zur Laufzeit ändert. Ich finde nur keine, wie man dynamisch das Feld ändert, das ich abrufen möchte.

Gibt es einen einfachen Weg, dies zu tun? Vielen Dank. Yipi

Bearbeiten:

List<Orders> results = OrdersService.GetOrders();

public class Orders
{
    [DataMember]
    public DateTime? Day
    [DataMember]
    public int? Order
    [DataMember]
    public int? Product
    [DataMember]
    public int? Cost
    [DataMember]
    public int? Price
    [DataMember]
    public int? Client
    [DataMember]
}

Beliebte Antwort

Sie können dieses Problem lösen, indem Sie den Lambda-Ausdruck manuell erstellen.

Die Abfrage, die Sie gerade verwenden, kann so geändert werden, dass sie die Methodenkettensyntax verwendet und dann wie folgt aussieht:

var query = results.Select(item => item.<filterName>.ToString()).Distinct();

Jetzt müssen wir den Lambda-Ausdruck erstellen, der an Distinct selbst übergeben wird.

Dies kann mit der folgenden Methode erreicht werden:

Expression<Func<YourResultType, string>> CreateExpression(string propertyName)
{
    var itemExpression = Expression.Parameter(typeof(YourResultType), "item");
    var propertyExpression = Expression.Property(itemExpression, propertyName);
    var toStringExpression = Expression.Call(propertyExpression,
                                             "ToString", null);
    return Expression.Lambda<Func<YourResultType, string>>(toStringExpression, 
                                                           itemExpression);
}

Jetzt können wir die Abfrage folgendermaßen ändern:

var query = results.Select(CreateExpression(filterName)).Distinct();

Beachten Sie, dass Sie YourResultType in den Typ der Instanzen in Ihrer results ändern YourResultType . Wenn Sie keine Datenbank, sondern eine In-Memory-Liste abfragen, müssen Sie die Abfrage folgendermaßen ändern:

var query = results.Select(CreateExpression(filterName).Compile()).Distinct();


Lizenziert unter: CC-BY-SA with attribution
Nicht verbunden mit Stack Overflow
Ist diese KB legal? Ja, lerne warum
Lizenziert unter: CC-BY-SA with attribution
Nicht verbunden mit Stack Overflow
Ist diese KB legal? Ja, lerne warum