Pregunta

Quiero escribir controles de filtrado que tomen el tipo de objeto T y el nombre de la propiedad y devuelvan Expression < Func < T, bool > > que verifica el valor de la propiedad pasada. No quiero usar la reflexión porque me temo que EF no puede usar tales expresiones. No puedo usar delegados porque C # no tiene delegados para las propiedades. ¿Que puedo hacer? Tal vez debería usar un enfoque diferente para escribir estos controles?

Aquí está mi primer enfoque utilizando la reflexión:

public string FilteringField { get; set; }
public Expression<Func<T, bool>> GetFilterExpression()
{
  if (cmbValue.SelectedIndex == 1)
    return (o => (bool)typeof(T).GetProperty(FilteringField).GetValue(o, null));
  if (cmbValue.SelectedIndex == 2)
    return (o => !(bool)typeof(T).GetProperty(FilteringField).GetValue(o, null));
  return null;
}
¿Fue útil?

Solución

La reflexión no es un problema aquí; EF ni siquiera podrá notar la diferencia. El enfoque de delegado es un no iniciador, por cierto (ya que mencionas EF); En última instancia, es algo como:

public static IQueryable<T> Where<T>(this IQueryable<T> query,
    string propertyName, object value)
{
    PropertyInfo prop = typeof(T).GetProperty(propertyName);
    var param = Expression.Parameter(typeof(T), "x");
    var body = Expression.Equal(
        Expression.Property(param, prop),
        Expression.Constant(value, prop.PropertyType)
        );
    var predicate = Expression.Lambda<Func<T, bool>>(body, param);
    return query.Where(predicate);
}

Tenga en cuenta que puede hacerlo más fácil con Expression.PropertyOrField (propertyName) ; La razón por la que no lo he utilizado aquí es que es muy útil conocer el tipo de miembro ( prop.PropertyType ) al crear la constante; de ??lo contrario, puede obtener problemas con nulos.

Otros consejos

Sé que esta es una respuesta antigua, pero si alguien ve esto, he creado este proyecto:

https://github.com/PoweredSoft/DynamicLinq

Que también debería ser descargable en nuget:

https://www.nuget.org/packages/PoweredSoft.DynamicLinq

y simplemente podrías hacerlo

query.Where("FirstName", ConditionOperators.Equal, "David");
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top