2010-10-20 4 views
0

J'ai une collection IEnumerable simple d'objets Order. Je veux écrire une fonction de tri générique qui accepte la collection et une clé de tri qui correspond à une propriété sur un objet Order. Je ne veux pas coder en dur les instructions de tri pour chaque propriété. Comment puis-je créer une chaîne LINQ dynamique qui génère automatiquement le LINQ pour moi? Voici ma fonction SortOrders() dans son état actuel:Aide LINQ dynamique pour le problème de tri

public IEnumerable<Order> SortOrders(IEnumerable<Order> orders, string sortKey) 
     { 
      // Sort order records 
      try 
      { 
       IEnumerable<Order> sortedOrders = new List<Order>(); 

       // Extract sort key and direction from combined sortKey input 
       string _sortKey = this.SortKey.Replace(" ASC", "").Replace(" DESC", ""); 
       bool sortASC = this.SortKey.EndsWith(" ASC"); 

       switch (_sortKey) 
       { 
        case "CustomerID": 
         sortedOrders = (sortASC) ? orders.OrderBy(o => o.CustomerID) : orders.OrderByDescending(o => o.CustomerID); 
         break; 
        case "CustomerAddress": 
         sortedOrders = (sortASC) ? orders.OrderBy(o => o.CustomerAddress) : orders.OrderByDescending(o => o.CustomerAddress); 
         break; 
        case "CustomerCity": 
         sortedOrders = (sortASC) ? orders.OrderBy(o => o.CustomerCity) : orders.OrderByDescending(o => o.CustomerCity); 
         break; 
        default: 
         sortedOrders = orders; 
         break; 
       } 
       return sortedOrders; 
      } 
      catch 
      { 
       return orders; // return original orders list in the event of errors 
      } 
     } 

Je cherche à remplacer toutes les sections de cas comme celui-ci:

case "CustomerID": 
         sortedOrders = (sortASC) ? orders.OrderBy(o => o.CustomerID) : orders.OrderByDescending(o => o.CustomerID); 

avec une seule directive comme celui-ci:

sortedOrders = (sortASC) ? orders.OrderBy(o => o.PropertyName) : orders.OrderByDescending(o => o.PropertyName); 

Répondre

1

Vous pouvez transmettre l'expression que vous souhaitez trier en tant que Lamba (ceci est simplifié/pseudocode)

SortOrders(IEnumerable<Order> orders, Func<Order, string> func) 
{ 
    sortedOrders = orders.OrderBy(func) 
    ....     
} 


// call: 
SortOrders(orders, o => o.CustomerID); 
+0

Ceci m'obtient à mi-chemin là ... Comment est-ce que je génère l'appel de fonction lui-même dynamiquement? En d'autres termes, si l'objet Order a N propriétés je veux être en mesure d'assembler la partie "o => o.OrderPropertyName" dynamiquement. Je ne veux pas avoir à coder en dur o => o.CustomerID. Merci de votre intérêt pour cette question. – Mark

+0

OK. Si vous voulez qu'il soit complètement dynamique, regardez l'autre réponse. Réalisez que vous n'avez pas besoin de «coder en dur» le lambda que vous utilisez pour trier. Vous pouvez le transmettre comme n'importe quelle variable. –

1

Vous pouvez utiliser Dynamic LINQ et la méthode d'extension n'est pas nécessaire. Utilisez simplement l'extension dans la classe DynamicQueryable et spécifiez la clé et la direction sous la forme d'une chaîne.

var sorted = orders.OrderBy("CustomerID desc");