Entity mit LINQ unter Verwendung des Dyanmic Field Name abfragen

c# dynamic-linq expression-trees lambda linq-to-entities

Frage

Ich habe einen dynamischen Suchbildschirm in ASP.NET MVC erstellt. Ich habe die Feldnamen aus der Entität durch Reflektion abgerufen, sodass ich dem Benutzer erlauben konnte, die Felder auszuwählen, nach denen gesucht werden soll, anstatt alle Felder in der Ansicht anzuzeigen.

Wenn das Suchergebnis an den Controller gesendet wird, erhalte ich eine FormCollection, die den Feldnamen und den Wert enthält. Ich weiß nicht, wie viele Felder gesucht werden, und die FormCollection enthält nur Felder, die vom Benutzer ausgewählt wurden.

Ich möchte diesen Feldnamen jetzt übernehmen und auf meine LINQ-Anweisung anwenden können, wenn ich beispielsweise die Datenbank abfrage:

public List<People> SearchPeople(Dictionary<string, string> fieldValueDictionary)
{
    List<People> searchResults = new List<People>();

    foreach (string key in fieldValueDictionary.Keys)
    {
         searchResults.Add(entities.People.Where(p => p.<use the key string as the fieldName> == fieldValueDictionary[key]));
    }

    return searchResults;
}

Wo ich "die Schlüsselzeichenkette als fieldName verwende", wäre es wie p => p.FirstName == fieldValueDictionary [Schlüssel] where Schlüssel = "FirstName". Ich habe versucht, Lambda Expression Trees zu verwenden, und habe mit Dynamic LINQ ein wenig Erfolg gehabt. Die einzige andere Alternative ist, etwas zu tun wie:

public List<People> SearchPeople(Dictionary<string, string> fieldValueDictionary)
{
    List<People> searchResults = new List<People>();

    foreach (string key in fieldValueDictionary.Keys)
    {
         searchResults.Add(entities.People.Where(p => p.<use the key string as the fieldName> == fieldValueDictionary[key]));
    }

    return searchResults;
}

UPDATE : Ich habe Lambda Expression Trees durch die folgenden Beiträge erforscht:

dynamisch lambdas Ausdrücke erstellen + linq + OrderByDescending

Parameterproblem mit Expression.Lambda ()

LINQ: Übergeben des Lambda-Ausdrucks als Parameter, der von der Methode ausgeführt und zurückgegeben werden soll

Ich bin so weit gekommen, ein Lambda zu bekommen, um folgendes auszugeben: "p => p.FirstName", aber ich kann das nicht in einem Wo funktionieren. Irgendwelche Vorschläge? Mein Code ist unten:

public List<People> SearchPeople(Dictionary<string, string> fieldValueDictionary)
{
    List<People> searchResults = new List<People>();

    foreach (string key in fieldValueDictionary.Keys)
    {
         searchResults.Add(entities.People.Where(p => p.<use the key string as the fieldName> == fieldValueDictionary[key]));
    }

    return searchResults;
}

Akzeptierte Antwort

Nach viel mehr Versuch und Irrtum und Suche habe ich zufällig einen anderen SO-Beitrag gefunden, der dasselbe Problem behandelt:

InvalidOperationException: Keine Methode 'Where' beim Typ 'System.Linq.Queryable' ist mit den angegebenen Argumenten kompatibel

Hier ist mein modifizierter Code, der funktioniert:

        IQueryable query = entities.People;
        Type[] exprArgTypes = { query.ElementType };

        string propToWhere = "FirstName";            

        ParameterExpression p = Expression.Parameter(typeof(People), "p");
        MemberExpression member = Expression.PropertyOrField(p, propToWhere);
        LambdaExpression lambda = Expression.Lambda<Func<People, bool>>(Expression.Equal(member, Expression.Constant("Scott")), p);                            

        MethodCallExpression methodCall = Expression.Call(typeof(Queryable), "Where", exprArgTypes, query.Expression, lambda);

        IQueryable q = query.Provider.CreateQuery(methodCall);

Mit einigen hoffentlich ziemlich einfachen Modifikationen, sollte ich in der Lage sein, dies mit jedem Typ zu arbeiten.

Danke nochmal für deine Antworten Ani & John Bowen


Beliebte Antwort

Haben Sie versucht, den Wert von PropertyInfo abzurufen?

entities.People.Where(p => (p.GetType().GetProperty(key).GetValue(p, null) as string) == fieldValueDictionary[key])



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