Question

Je souhaite écrire des contrôles de filtrage qui prennent le type d'objet T , le nom de la propriété et renvoient Expression < Func < T, bool > vérifiant la valeur de la propriété transmise. Je ne veux pas utiliser la réflexion parce que je crains que de telles expressions ne soient pas utilisées par EF. Je ne peux pas utiliser de délégués car C # n'a pas de délégués pour les propriétés. Que puis-je faire? Peut-être que je devrais utiliser une approche différente pour écrire ces contrôles?

Voici ma première approche utilisant la réflexion:

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;
}
Était-ce utile?

La solution

La réflexion n’est pas un problème ici; EF ne sera même pas capable de remarquer la différence. L'approche des délégués est un non-starter, à propos (puisque vous mentionnez EF); en fin de compte, c'est quelque chose comme:

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);
}

Notez que vous pouvez simplifier la tâche avec Expression.PropertyOrField (propertyName) ; La raison pour laquelle je ne l'ai pas utilisée ici est qu'il est très pratique de connaître le type de membre ( prop.PropertyType ) lors de la création de la constante - sinon, vous pouvez avoir des problèmes avec les valeurs NULL.

Autres conseils

Je sais que c'est une vieille réponse, mais si quelqu'un voit ça, j'ai construit ce projet:

https://github.com/PoweredSoft/DynamicLinq

Ce qui devrait également être téléchargeable sur le nuget:

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

et vous pourriez simplement faire

query.Where("FirstName", ConditionOperators.Equal, "David");
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top