Comment construire dynamiquement une méthode de prédicat à partir d'un arbre d'expression?

expression-trees filter predicatebuilder silverlight

Question

Voici le scénario: Silverlight 4.0, DataGrid, PagedCollectionView itemssource. L'objectif est d'appliquer un filtre au PCV. Le filtre doit être un Predicate<object>(Method) - où Method implémente une logique par rapport à l'objet et renvoie true / false pour l'inclusion. Ce que j'ai est un besoin d'inclure éventuellement 3 critères différents dans la logique de filtrage et le code explicite devient rapidement laid. Nous ne voulons pas cela, n'est-ce pas?

Je vois donc qu'il existe un moyen de construire un arbre d'expression en utilisant PredicateBuilder et de le transmettre à Linq.Where, a la:

IQueryable<Product> SearchProducts (params string[] keywords)
{
  var predicate = PredicateBuilder.False<Product>();

  foreach (string keyword in keywords)
  {
    string temp = keyword;
    predicate = predicate.Or (p => p.Description.Contains (temp));
  }
  return dataContext.Products.Where (predicate);
}

[Ce n'est pas ce que j'essaye de faire en passant]

Avec 3 critères optionnels, je veux écrire quelque chose comme:

IQueryable<Product> SearchProducts (params string[] keywords)
{
  var predicate = PredicateBuilder.False<Product>();

  foreach (string keyword in keywords)
  {
    string temp = keyword;
    predicate = predicate.Or (p => p.Description.Contains (temp));
  }
  return dataContext.Products.Where (predicate);
}

Bien entendu, cela ne compilera pas car PredicateBuilder crée une Expression<Func<T, bool>> non une méthode de prédicat réelle. Mais je vois qu’il existe des moyens de convertir un arbre d’expression en une méthode, alors il me semblait qu’il devrait exister un moyen d’accomplir ce que je recherche sans recourir à un ensemble d’énoncés imbriqués if / then / else.

La question est donc la suivante: existe-t-il un moyen de créer une méthode de prédicat de manière dynamique?

TIA

Réponse populaire

pour faire cela pour un PagedCollectionView, vous devez avoir un prédicat. Donc, il ressemble à:

private Predicate<object> ConvertExpressionToPredicate(Expression<Func<object, bool>> exp)
{
  Func<object, bool> func = exp.Compile();
  Predicate<object> predicate = new Predicate<object>(func);
  //Predicate<object> predicate = t => func(t);     // also works
  //Predicate<object> predicate = func.Invoke;      // also works
  return predicate;
}

et construisez l'expression:

private Predicate<object> ConvertExpressionToPredicate(Expression<Func<object, bool>> exp)
{
  Func<object, bool> func = exp.Compile();
  Predicate<object> predicate = new Predicate<object>(func);
  //Predicate<object> predicate = t => func(t);     // also works
  //Predicate<object> predicate = func.Invoke;      // also works
  return predicate;
}

puis définissez le filtre:

private Predicate<object> ConvertExpressionToPredicate(Expression<Func<object, bool>> exp)
{
  Func<object, bool> func = exp.Compile();
  Predicate<object> predicate = new Predicate<object>(func);
  //Predicate<object> predicate = t => func(t);     // also works
  //Predicate<object> predicate = func.Invoke;      // also works
  return predicate;
}



Sous licence: CC-BY-SA with attribution
Non affilié à Stack Overflow
Est-ce KB légal? Oui, apprenez pourquoi
Sous licence: CC-BY-SA with attribution
Non affilié à Stack Overflow
Est-ce KB légal? Oui, apprenez pourquoi