2009-04-29 11 views
1
public class Person 
{ 
    public string name { get; set; } 
    public Email email { get; set; } 

} 

public class Email 
{ 
    public string desc { get; set; } 
} 

public static IEnumerable<T> Sort<T>(this IEnumerable<T> source, string sortExpression, bool desc) 
{    
    var param = Expression.Parameter(typeof(T), string.Empty); 
    try 
    { 
     var property = Expression.Property(param, sortExpression); 
     var sortLambda = Expression.Lambda<Func<T, object>>(Expression.Convert(property, typeof(object)), param); 

     if (desc) 
     { 
      return source.AsQueryable<T>().OrderByDescending<T, object>(sortLambda); 
     } 

     return source.AsQueryable<T>().OrderBy<T, object>(sortLambda); 
    } 
    catch (ArgumentException) 
    { 
     return source; 
    } 
} 

     List<Person> vet = new List<Person>(); 

     Person p = new Person { name = "aaa", email = new Email { desc = "[email protected]" } }; 
     Person pp = new Person { name = "bbb", email = new Email { desc = "[email protected]" } }; 
     vet.Add(p); 
     vet.Add(pp); 

     vet.Sort("name",true); //works 
     vet.Sort("email.desc",true) // doesnt work 

jemand kann mir helfen?Erweiterungsmethode, um eine Liste innerhalb eines übergeordneten Objekts zu sortieren

Antwort

1

Wenn Sie diese Funktionalität in einen Artikel von ScottGu auf der Dynamic Linq Library suchen möchten. Ich glaube, es wird tun, was Sie wollen.

Während Lambda-Typen typsicher sind, gibt es Zeiten, in denen Sie die Abfrage dynamisch generieren möchten, anstatt jede mögliche Kombination zu haben, die ein Benutzer zum Beispiel sortieren kann.

bearbeiten

fixiert ich Ihre Methode. Grundsätzlich müssen Sie für jeden Mitgliedzugriff einen Ausdruck erstellen.

public static IEnumerable<T> Sort<T>(this IEnumerable<T> source, string sortExpression, bool desc) 
    { 
     var param = Expression.Parameter(typeof(T), string.Empty); 
     try 
     { 
      var fields = sortExpression.Split('.'); 
      Expression property = null; 
      Expression parentParam = param; 
      foreach (var field in fields) 
      { 
       property = Expression.Property(parentParam, field); 
       parentParam = property; 

      } 

      var sortLambda = 
       Expression.Lambda<Func<T, object>>(
        Expression.Convert(property, typeof(object)), param); 

      if (desc) 
      { 
       return source.AsQueryable<T>(). 
        OrderByDescending<T, object>(sortLambda); 
      } 

      return source.AsQueryable<T>(). 
       OrderBy<T, object>(sortLambda); 
     } 
     catch (ArgumentException) 
     { 
      throw; 
     } 
    } 
2

Sie möchten vielleicht über eine andere Methode nachdenken, die ein benutzerdefiniertes Comparer-Objekt für den Vergleich verwendet. Sie könnten dann einen benutzerdefinierten Comparer für Person schreiben, der sie anhand ihrer E-Mail-Adressen vergleicht.

Verwandte Themen