IQueryable-Erweiterung: erstellen lambda-Ausdruck für die Abfrage eine Spalte nach einem Schlüsselwort
Begann ich mit dem IQueryable Erweiterung Methoden aus diesem Beispiel auf CodePlex.
Was ich glaube, was ich brauche, ist ein IQueryable-extension Methode "Where", wo die Signatur der Methode sieht wie folgt aus:
public static IQueryable<T> Where<T>(this IQueryable<T> source, string columnName, string keyword)
effektiv und tut dies (vorausgesetzt, T. Spaltenname vom Typ string):
source.Where(p => p.ColumnName.Contains("keyword"))
mithilfe der oben genannten CodePlex Beispiel, ich glaube, ich verstehe, wie er die OrderBy-Methode arbeiten, aber mein problem scheint etwas komplexer und ich weiß nicht, wie man die Contains("keyword") Teil der Arbeit.
Vielen Dank im Voraus,
--Ed
Update: 9/13/2010 6:26pm PST
Ich dachte, die folgenden funktionieren würde, aber am Ende immer eine NotSupportedException (Die LINQ-Ausdruck ein node-type 'Invoke' wird nicht unterstützt LINQ to Entities.) wenn ich ausführen, die den Ausdruck über Count(). Irgendwelche Ideen?
public static IQueryable<T> Where<T>(this IQueryable<T> source, string columnName, string keyword)
{
var type = typeof(T);
var property = type.GetProperty(columnName);
if (property.PropertyType == typeof(string))
{
var parameter = Expression.Parameter(type, "p");
var propertyAccess = Expression.MakeMemberAccess(parameter, property);
var sel = Expression.Lambda<Func<T, string>>(propertyAccess, parameter);
var compiledSel = sel.Compile();
return source.Where(item => compiledSel(item).Contains(keyword));
}
else
{
return source;
}
}
InformationsquelleAutor Ed Sinek | 2010-09-13
Du musst angemeldet sein, um einen Kommentar abzugeben.
Geändert
T
zustring
. Ist das besser?Ich denke, es braucht zwei stellen. Eine für die Zeichenfolge.Enthält und ein weiteres für das Wo. var stringBody = Ausdruck.Call( typeof(string), "Enthält", new Type[] { typeof(string) }, Ausdruck.Eigenschaft(arg, Spaltenname) Ausdruck.Konstanten(Schlüsselwort)); var whereBody = Ausdruck.Call( typeof(Queryable), "Wo", new Type[] { typeof(Queryable) }, -- dies ist, wo ich verloren gehen.
Ihre
whereBody
ist genau das, wasreturn source.Where(predicate);
in meinem code gibt. Es baut zuerst das Prädikatp => p.ColumnName.Contains("keyword")
und dann zurücksource.Where(predicate)
.noch immer "Keine Methode" Contains "gibt es auf den Typ" System.String'." Irgendwelche Ideen? In den Körper habe ich beide verändert "typeof" string da Queryable.Enthält<T>(das IQueryable - <T>,...) nicht funktionieren würde
InformationsquelleAutor dtb
Sowie ein paar Jahre später, aber wenn noch jemand braucht, hier ist es:
Rief ich meine Methode "Hat" Sie nur, es kurz zu halten, ein Beispiel für die Verwendung:
Und Sie verketten können, um es noch mehr Ausdruckskraft:
Durch die Art und Weise, die "IsNull ()", die an den Saiten ist nur ein simple Methode:
InformationsquelleAutor Chris Rivera
Den
.Contains("keyword")
Teil ist genau das richtige in deinem Beispiel.Es ist die
p.ColumnName
Teil, das wird Probleme verursachen.Nun, es gibt eine Reihe von Möglichkeiten, dies zu tun, in der Regel, die entweder die Reflexions-oder
Expression<>
, von denen keines besonders effizient.Das problem ist hier, indem die Spalte name als Zeichenfolge, die Sie tun, um rückgängig zu machen, genau das, was LINQ erfunden wurde, um zu ermöglichen.
Allerdings gibt es wahrscheinlich bessere Möglichkeiten Ihre Allgemeine Aufgabe, neben, Weg.
So, schauen wir uns Alternative Möglichkeiten:
Möchten Sie in der Lage sein zu sagen :
habe und es war das äquivalent von
Wie 'bout wir gehen mit:
oder
Diese sind leicht erweitert für alternativen:
InformationsquelleAutor James Curran
Sehen, in Generika-Typ des Objekts dynamisch arbeitet. Wenn also p.ColumnName als string, der Enthält der string wird ausgeführt wurden.
In der Regel für jeden lambda-Ausdruck angeben werden, es analysiert das Ding in einen Ausdruck und führt die Ausgabe zur Laufzeit.
Wenn Ihr meinen post :
http://www.abhisheksur.com/2010/09/use-of-expression-trees-in-lamda-c.html
Sie werden verstehen, wie es funktioniert tatsächlich.
InformationsquelleAutor abhishek