30 sept 2010

Max de un IEnumerable<T>

Voy a explicar como aplicar una típica función agregada de SQL: Max, sobre un IEnumerable<T>, a partir de un campo de ese T que van a tener todos los tipos que puedan mapearse contra ese tipo T.

Hay dos formas de aplicarlo.


1) Forma más explicativa:


public int GetMaxId<T>(IEnumerable<T> listx, string campo)
{
//Aquí mediante reflection obtenemos el valor de la propiedad cuyo nombre nos llega por parámetro
Expression> exp = o => Convert.ToInt32(typeof(T).GetProperty(campo).GetValue(o, null));

//Luego agregamos el tipo de datos y la propiedad del T que nos interesa tomar en cuenta
var list = Expression.Parameter(typeof(IEnumerable), campo);

//Luego construimos la expresión del Max en sí misma, notar que en lugar de Max podría ir otra función SQL
MethodCallExpression maxExp = Expression.Call(typeof(Enumerable), "Max"
new Type[] { typeof(T), exp.Body.Type }, list, exp);

//Por último generamos la expresión lambda
var lambda = Expression.Lambda , int>>(maxExp, list);

//y la ejecutamos, obteniendo el max de la propiedad "campo" de listx.
var result = lambda.Compile()(listx);
}

Luego para probarlo bastaría con hacer lo siguiente:

......
...

static void Main()
{
List<Cliente> listClients = new List<Cliente>();
listClients.Add(new Cliente { Edad = 20 });
listClients.Add(new Cliente { Edad = 22 });
listClients.Add(new Cliente { Edad = 24 });

int max = GetMaxId<Cliente>(listClients, "Edad");

}

......
...

class Cliente
{
public int Edad { get; set; }
}


2) Luego la forma más simple que se reduce a una línea de código es la siguiente:

public int GetMaxId<T>(IEnumerable<T> listx, string campo)
{
return listx.Max(o => Convert.ToInt32(typeof(T).GetProperty(campo).GetValue(o, null));
}


Saludos,
Mike

No hay comentarios:

Publicar un comentario