Ich habe ein Beispiel in der VS2008 Beispiele für Dynamic LINQ, mit dem Sie eine SQL-ähnliche Zeichenfolge verwenden können (z. B. OrderBy("Name, Age DESC"))
für die Bestellung. Leider funktioniert die enthaltene Methode nur bei IQueryable<T>
. Gibt es eine Möglichkeit, diese Funktionalität auf IEnumerable<T>
?
Antworten
Zu viele Anzeigen?Ich habe versucht, dies zu tun, hatte aber Probleme mit Die Lösung von Kjetil Watnedal weil ich die Inline-Linq-Syntax nicht verwende - ich bevorzuge die Syntax im Methodenstil. Mein spezifisches Problem war beim Versuch, dynamische Sortierung mit einer benutzerdefinierten IComparer
.
Meine Lösung sah folgendermaßen aus:
Gegeben eine IQueryable Abfrage wie so:
List<DATA__Security__Team> teams = TeamManager.GetTeams();
var query = teams.Where(team => team.ID < 10).AsQueryable();
Und mit einem Argument für das Sortierfeld zur Laufzeit:
string SortField; // Set at run-time to "Name"
Der dynamische OrderBy sieht folgendermaßen aus:
query = query.OrderBy(item => item.GetReflectedPropertyValue(SortField));
Und zwar mit einer kleinen Hilfsmethode namens GetReflectedPropertyValue():
public static string GetReflectedPropertyValue(this object subject, string field)
{
object reflectedValue = subject.GetType().GetProperty(field).GetValue(subject, null);
return reflectedValue != null ? reflectedValue.ToString() : "";
}
Eine letzte Sache - ich erwähnte, dass ich die OrderBy
benutzerdefiniert zu verwenden IComparer
- weil ich etwas tun wollte Natürliche Sortierung .
Dazu ändere ich einfach die OrderBy
zu:
query = query.OrderBy(item => item.GetReflectedPropertyValue(SortField), new NaturalSortComparer<string>());
Ver diese Stelle für den Code für NaturalSortComparer()
.
Nach langem Suchen hat das bei mir funktioniert:
public static IEnumerable<TEntity> OrderBy<TEntity>(this IEnumerable<TEntity> source,
string orderByProperty, bool desc)
{
string command = desc ? "OrderByDescending" : "OrderBy";
var type = typeof(TEntity);
var property = type.GetProperty(orderByProperty);
var parameter = Expression.Parameter(type, "p");
var propertyAccess = Expression.MakeMemberAccess(parameter, property);
var orderByExpression = Expression.Lambda(propertyAccess, parameter);
var resultExpression = Expression.Call(typeof(Queryable), command,
new[] { type, property.PropertyType },
source.AsQueryable().Expression,
Expression.Quote(orderByExpression));
return source.AsQueryable().Provider.CreateQuery<TEntity>(resultExpression);
}
Sie könnten es hinzufügen:
public static IEnumerable<T> OrderBy( this IEnumerable<T> input, string queryString) {
//parse the string into property names
//Use reflection to get and sort by properties
//something like
foreach( string propname in queryString.Split(','))
input.OrderBy( x => GetPropertyValue( x, propname ) );
// I used Kjetil Watnedal's reflection example
}
El GetPropertyValue
Funktion ist von Antwort von Kjetil Watnedal
Die Frage wäre, warum? Eine solche Art würde Ausnahmen zur Laufzeit und nicht zur Kompilierzeit auslösen (wie die Antwort von D2VIANT).
Wenn Sie mit Linq to Sql arbeiten und das orderby ein Ausdrucksbaum ist, wird es zur Ausführung ohnehin in SQL konvertiert.