Tengo el nombre de "ordenar por propiedad" en una cadena. Necesitaré usar Lambda / Linq para ordenar la lista de objetos.
Ex:
public class Employee
{
public string FirstName {set; get;}
public string LastName {set; get;}
public DateTime DOB {set; get;}
}
public void Sort(ref List<Employee> list, string sortBy, string sortDirection)
{
//Example data:
//sortBy = "FirstName"
//sortDirection = "ASC" or "DESC"
if (sortBy == "FirstName")
{
list = list.OrderBy(x => x.FirstName).toList();
}
}
- En lugar de usar un montón de ifs para verificar el nombre del campo (sortBy), ¿hay una forma más limpia de ordenar?
- ¿Es consciente el tipo de datos?
c#
linq
lambda
linq-to-objects
DotnetDude
fuente
fuente
==
... ¿qué?Respuestas:
Esto se puede hacer como
El marco .NET está convirtiendo el lambda
(emp1,emp2)=>int
como unComparer<Employee>.
Esto tiene la ventaja de ser fuertemente tipado.
fuente
list.sort(functionDeclaredElsewhere)
Una cosa que podría hacer es cambiar
Sort
para que aproveche mejor las lambdas.Ahora puede especificar el campo para ordenar al llamar al
Sort
método.fuente
Puede usar Reflection para obtener el valor de la propiedad.
Donde TypeHelper tiene un método estático como:
También es posible que desee ver Dynamic LINQ de la biblioteca de muestras VS2008 . Puede usar la extensión IEnumerable para emitir la Lista como IQueryable y luego usar la extensión de enlace dinámico OrderBy.
fuente
collection.ToList().OrderBy(x => TypeHelper.GetPropertyValue( x, sortBy)).ToList();
Así es como resolví mi problema:
fuente
La construcción del orden por expresión se puede leer aquí
Descaradamente robado de la página en el enlace:
fuente
Puede usar la reflexión para acceder a la propiedad.
Notas
fuente
Ordenar utiliza la interfaz IComparable, si el tipo lo implementa. Y puede evitar los ifs implementando un IComparer personalizado:
y entonces
fuente
Respuesta para 1 .:
Debería poder construir manualmente un árbol de expresión que se pueda pasar a OrderBy utilizando el nombre como una cadena. O podría usar la reflexión como se sugiere en otra respuesta, que podría ser menos trabajo.
Editar : Aquí hay un ejemplo práctico de cómo construir un árbol de expresión manualmente. (Ordenando en X.Value, solo conociendo el nombre "Value" de la propiedad) Podría (debería) construir un método genérico para hacerlo.
Sin embargo, construir un árbol de expresión requiere que conozca los tipos de participación. Eso podría o no ser un problema en su escenario de uso. Si no sabe en qué tipo debe ordenar, será más fácil usar la reflexión.
Respuesta para 2 .:
Sí, dado que Comparer <T> .Default se usará para la comparación, si no define explícitamente el comparador.
fuente
Otro, esta vez para cualquier IQueryable:
Puede pasar varios criterios de clasificación, como este:
fuente
Desafortunadamente, la solución proporcionada por Rashack no funciona para los tipos de valor (int, enums, etc.).
Para que funcione con cualquier tipo de propiedad, esta es la solución que encontré:
fuente
Además de lo que hicieron @Samuel y @bluish. Esto es mucho más corto ya que Enum no era necesario en este caso. Además, como una ventaja adicional cuando el Ascendente es el resultado deseado, puede pasar solo 2 parámetros en lugar de 3, ya que verdadero es la respuesta predeterminada al tercer parámetro.
fuente
Si obtiene el nombre de la columna de clasificación y la dirección de clasificación como una cadena y no desea utilizar el interruptor o la sintaxis if \ else para determinar la columna, este ejemplo puede ser interesante para usted:
Solución basada en el uso del Diccionario que conecta lo necesario para ordenar la columna a través de Expresión> y su cadena clave.
fuente