2011-04-28 9 views
6

¿Hay alguna manera de ordenar un List<T> usando una cadena como "Name desc" (igual que DataTable.DefaultView.Sort) en lugar de Linq?Lista de clasificación <T> usando cadena sin Linq

Estoy tratando de reemplazar DataTables con Lists y lo necesito para hacer esto para que sea compatible con el código anterior.

SOLUCIÓN

utilizando el código de V4Vendetta yo era capaz de crear este método de extensión, las pruebas parecen mostrar que funcione.

public static void SortByString<T>(this List<T> list, string sortString) 
{ 
    if (sortString == null) return; 

    List<string> SortGroups = sortString.Split(',').ToList(); 

    for (int i = SortGroups.Count - 1; i >= 0; i--)// sort from the last group first 
    { 
     string tempColumn = SortGroups[i].Trim().Split(' ')[0]; 
     bool isAsc = SortGroups[i].Trim().Split(' ').Length > 1 ? SortGroups[i].Trim().Split(' ')[1].ToLower() == "asc" ? true : false : true; 

     PropertyInfo propInfo = typeof(T).GetProperty(tempColumn); 
     if (propInfo == null) // if null check to make sure its not just a casing issue. 
     { 
      foreach (PropertyInfo pi in typeof(T).GetProperties()) 
      { 
       if(pi.Name.ToLower() == tempColumn.ToLower()) 
       { 
        tempColumn = pi.Name; 
        propInfo = typeof(T).GetProperty(tempColumn); 
        break; 
       } 
      } 
     } 

     if (propInfo != null) 
     { 
      Comparison<T> compare = delegate(T a, T b) 
      { 
       object valueA = isAsc ? propInfo.GetValue(a, null) : propInfo.GetValue(b, null); 
       object valueB = isAsc ? propInfo.GetValue(b, null) : propInfo.GetValue(a, null); 

       return valueA is IComparable ? ((IComparable)valueA).CompareTo(valueB) : 0; 
      }; 

      list.Sort(compare); 
     }else{ 
      throw new IndexOutOfRangeException("Property: '" + tempColumn + "', does not exist in '" + typeof(T).ToString() + "'"); 
     } 


    } 
} 

Respuesta

2

que había intentado algo en estas líneas tal vez usted necesita para improvisar una cit para su necesidad

private List<Employee> CreateSortList<T>(
        IEnumerable<Employee> dataSource, 
        string fieldName, SortDirection sortDirection) 
    { 
     List<Employee> returnList = new List<Employee>(); 
     returnList.AddRange(dataSource); 
     // get property from field name passed 
     System.Reflection.PropertyInfo propInfo = typeof(T).GetProperty(fieldName); 
     Comparison<Employee> compare = delegate(Employee a, Employee b) 
     { 
      bool asc = sortDirection == SortDirection.Ascending; 
      object valueA = asc ? propInfo.GetValue(a, null) : propInfo.GetValue(b, null); 
      object valueB = asc ? propInfo.GetValue(b, null) : propInfo.GetValue(a, null); 
      //comparing the items 
      return valueA is IComparable ? ((IComparable)valueA).CompareTo(valueB) : 0; 
     }; 
     returnList.Sort(compare); 
     return returnList; 
    } 

Tiene que pasar en el dirección de ordenación apropiada y el nombre del campo que sería propiedad de la clase (en mi caso Empleado)

espero que esto ayude

+0

@ g.foley ¿Te ayudó esto? – V4Vendetta

+0

sí, esto ayudó más. Gracias –

0

que he tenido éxito con la biblioteca de consultas LINQ dinámica en el pasado: http://weblogs.asp.net/scottgu/archive/2008/01/07/dynamic-linq-part-1-using-the-linq-dynamic-query-library.aspx

+0

es curioso teniendo en cuenta el bi t sobre "sin Linq" en el título de esta pregunta. – slumtrimpet

+0

No es raro que las personas combinen LINQ con los métodos de extensión fuertemente tipados. La biblioteca de consulta dinámica le permite ordenar una lista usando una cadena, lo que podría haber sido útil. – roufamatic

3

List tiene algunos métodos de clasificación y algunos tomar una Comparison<T> que se puede implementar para tener una comparación personalizada de clasificación

+0

Intenté esto y aprendí en el camino. Pero estaba más feliz con la solución anterior, gracias –

0

Mire el espacio de nombre de colecciones especializadas. Debería haber una lista ordenada allí.

3

No hay soporte incorporado para este tipo de búsqueda hasta donde yo sé. Entonces, deberás escribir el tuyo.

No debería ser demasiado difícil analizar la cadena. Dividirlo en comas (,) en caso de que tenga una cadena de ordenación como "nombre asc, edad desc" y tratar cada uno como un nombre y una dirección. Luego puede usar la reflexión sobre el tipo T para encontrar la propiedad para ordenar y construir un método que realice la comparación necesaria.

vistazo a este artículo en CodePlex para ver un ejemplo: http://www.codeproject.com/KB/linq/dynamite_dynamic_sorting.aspx

+0

Utilicé esta idea general, gracias por la ayuda. –

Cuestiones relacionadas