2009-09-11 4 views
2

Je souhaite écrire des contrôles de filtrage qui prennent le type d'objet T et le nom de la propriété et renvoient Expression<Func<T, bool>> qui vérifie la valeur de la propriété passée. Je ne veux pas utiliser la réflexion parce que je crains que de telles expressions ne puissent pas être 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?Générer l'expression <> pour le filtrage par une propriété arbitraire

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; 
} 
+0

Peut vous s'il vous plaît clarifier votre question? Pouvez-vous donner un exemple? –

Répondre

3

La réflexion est pas un problème ici; EF ne sera même pas capable de remarquer la différence. L'approche de délégué est une non-starter, d'ailleurs (puisque vous mentionnez EF); en fin de compte, il 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 le rendre plus facile avec Expression.PropertyOrField(propertyName); la raison pour laquelle je n'ai pas utilisé cela 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 obtenir des problèmes avec des valeurs nulles.