Sintaxis LINQ: OrderBy
OrderBy y OrderByDescending
Al igual que ocurre en SQL muchas veces es necesario que el resultado de una query este ordenado por uno o varios campos. Esto en LINQ se pude conseguir mediante el uso de la palabra clave orderby. Orderby, por defecto, devuelve el resultado ordenador ascendentemente y orderbyDescending lo hace descendentemente. Aquí podemos ver las signaturas de los dos métodos:
1: public static IOrderedSequence<TSource> OrderBy<TSource, TKey>(
2: this IEnumerable<TSource> source,
3: Func<TSource, TKey> keySelector)
4:
5: public static IOrderedSequence<TSource> OrderBy<TSource, TKey>(
6: this IEnumerable<TSource> source,
7: Func<TSource, TKey> keySelector,
8: IComparer<TKey> comparer)
9:
10: public static IOrderedSequence<TSource> OrderByDescending<TSource, TKey>(
11: this IEnumerable<TSource> source,
12: Func<TSource, TKey> keySelector)
13:
14: public static IOrderedSequence<TSource> OrderByDescending<TSource, TKey>(
15: this IEnumerable<TSource> source,
16: Func<TSource, TKey> keySelector,
17: IComparer<TKey> comparer)
Una cosa interesante que podemos ver en las signaturas de los métodos es que una de ellas permite la customización de la operación de comparación. Esto puede resultar muy útil en algunos escenarios.
Un ejemplo de la utilización de la palabra clave orderby sería el siguiente: queremos mostrar una lista con todos los desarrolladores de C# que tenemos en nuestra colección.
1: var list = from d in developers
2: where d.Language == "C#"
3: orderby d.Name
4: select d.Name;
5:
6: var list = developers.Where(d => d.Language == "C#")
7: .OrderBy(d => d.Name)
8: .Select(d => d.Name);
9:
10: var list = developers.Where(d => d.Language == "C#")
11: .OrderBy(d => d.Name,new CaseInsensitiveComparer())
12: .Select(d => d.Name);
13:
14: public class CaseInsensitiveComparer : IComparer<string>
15: { 16: public int Compare(string x, string y)
17: { 18: return string.Compare(x, y, true);
19: }
20: }
Si en cambio queremos la lista ordenada descendentemente deberías ejecutar las siguientes queries.
1: var list = from d in developers
2: where d.Language == "C#"
3: orderby d.Name descending
4: select d.Name;
5:
6: var list = developers.Where(d => d.Language == "C#")
7: .OrderByDescending(d => d.Name)
8: .Select(d => d.Name);
9:
10: var list = developers.Where(d => d.Language == "C#")
11: .OrderByDescending(d => d.Name,
12: new CaseInsensitiveComparer())
13: .Select(d => d.Name);
14:
15: public class CaseInsensitiveComparer : IComparer<string>
16: { 17: public int Compare(string x, string y)
18: { 19: return string.Compare(x, y, true);
20: }
21: }
ThenBy y ThenByDescending
La filosofía de ThenBy y ThenByDescending es la misma que la de Orderby sólo que permitir ordenar por varios campos al mismo tiempo. Las signaturas de los métodos son las siguientes:
1: public static IOrderedSequence<TSource> ThenBy<TSource, TKey>(
2: this IOrderedSequence<TSource> source,
3: Func<TSource,
4: TKey> keySelector)
5:
6: public static IOrderedSequence<TSource> ThenBy<TSource, TKey>(
7: this IOrderedSequence<TSource> source,
8: Func<TSource, TKey> keySelector,
9: IComparer<TKey> comparer)
10:
11: public static IOrderedSequence<TSource> ThenByDescending<TSource, TKey>(
12: this IOrderedSequence<TSource> source,
13: Func<TSource, TKey> keySelector)
14:
15: public static IOrderedSequence<TSource> ThenByDescending<TSource, TKey>(
16: this IOrderedSequence<TSource> source,
17: Func<TSource, TKey> keySelector,
18: IComparer<TKey> comparer)
Al igual que ocurre en los métodos anteriores una de las sobrecargas de las signaturas permite la opción de personalizar el proceso de comparación de la operación de ordenado.
Veamos unos ejemplos de como podemos usar esto dos nuevos métodos.
1: var list = from d in developers
2: orderby d.Language, d.Name
3: select d.Name;
4:
5: var list = developers.OrderByDescending(d => d.Language)
6: .ThenBy(d => d.Name)
7: .Select(d => d.Name);
8:
9: var list = developers.OrderByDescending(d => d.Name,
10: new CaseInsensitiveComparer())
11: .ThenBy(d => d.Name)
12: .Select(d => d.Name);
En el caso de necesitar el resultardo ordenado descendentemente podemos ver los siguiente ejemplos:
1: var list = from d in developers
2: orderby d.Language descending, d.Name
3: select d.Name;
4:
5: var list = developers.OrderBy(d => d.Language)
6: .ThenByDescending(d => d.Name)
7: .Select(d => d.Name);
8:
9: var list = developers.OrderBy(d => d.Name,
10: new CaseInsensitiveComparer())
11: .ThenByDescending(d => d.Name)
12: .Select(d => d.Name);
Reverse
En algunas ocasiones es necesario dar la vuelta al resultado de la query, es decir, que el último elemento pase a ser el primero. Para ello, es necesario utilizar el operador Reverse. Su signatura es la siguiente:
1: public static IEnumerable<TSource> Reverse<TSource>(
2: this IEnumerable<TSource> source
Aunque lo busquéis, C# 3.0 no tiene una palabra clave para este método, esto es debido a que no se le ha asignado un alias, así que hay que utilizar el método directamente. Un ejemplo de cómo utilizar este método.
1: var list = (from d in developers
2: where d.Language == "C#"
3: orderby d.Name
4: select d.Name).Reverse();
Nota: Para la realización de estos ejemplo se han utilizado una serie entidades y colecciones que podréis encontrar aquí.