2010-08-08 5 views
1

J'ai une méthode qui ont cette signatureLes arbres d'expression dans NHibernate

public static IList<T> GetBy<T>(System.Linq.Expressions.Expression<Func<T, bool>> expression) 

-je utiliser pour passer des expressions lambda et faire restriction de recherche dans NHibernate en récupérant les données de expressiontree.

Ainsi, lorsque la classe utilisateur passe quelque chose comme:

c => c.fullName == "John" && c.lastName == "Smith" && c.lastName != "" || c.fullName != "" && c.Age > 18 

Je reçois de lire cette structure de l'arbre d'expression, de cette façon que j'ai une façon IntelliSense complète pour fournir la recherche critères

En d'autres termes: I besoin de passer des critères à la recherche à la couche d'accès aux données (NHibernate)

Je dois extraire des critères d'arbre d'expression et de passer ensuite à mise en veille prolongée n par exemple:

c=>c.fullname = "John" 

je vais extraire les informations suivantes de l'arbre d'expression:

propertyname = fullname , value = "John" , restrictiontype = "equality" 

et ensuite passer cette information à NHibernate comme suit:

ICriteria crit = session.CreateCriteria(typeof(T)); 
        crit.Add(Restrictions.Eq(propretyName, value)); 
    IList<T> list = crit.Add(List<T>()) 
        return list; 

De toute façon le problème est-il est vraiment difficile à lire de expressiontree, donc je me demandais si vous avez un moyen facile d'itérer dans expressiontree pour extraire des données, ou peut-être que vous avez du code pour extraire des données d'ExpressionTree.

+1

j'ai modifié la question fournissant plus d'informations, désolé – Stacker

Répondre

5

Voici un code qui récupère les informations que vous avez mentionné. Je suis sûr que vous pouvez étendre cela pour inclure des informations supplémentaires que vous pourriez rechercher.

public class Criterion 
{ 
    public string PropertyName; 
    public object Value; 
    public ExpressionType RestrictionType; 
} 

[....] 

public static IEnumerable<Criterion> GetCriteria<T>(Expression<Func<T, bool>> expression) 
{ 
    return getCriteria<T>(expression.Body); 
} 
private static IEnumerable<Criterion> getCriteria<T>(Expression expression) 
{ 
    if (expression is BinaryExpression) 
    { 
     var bin = (BinaryExpression) expression; 
     if (bin.NodeType == ExpressionType.And || bin.NodeType == ExpressionType.AndAlso || 
      bin.NodeType == ExpressionType.Or || bin.NodeType == ExpressionType.OrElse) 
      return getCriteria<T>(bin.Left).Concat(getCriteria<T>(bin.Right)); 

     if (bin.Left is MemberExpression) 
     { 
      var me = (MemberExpression) bin.Left; 
      if (!(bin.Right is ConstantExpression)) 
       throw new InvalidOperationException("Constant expected in criterion: " + bin.ToString()); 
      return new[] { new Criterion { 
       PropertyName = me.Member.Name, 
       Value = ((ConstantExpression) bin.Right).Value, 
       RestrictionType = bin.NodeType 
      } }; 
     } 

     throw new InvalidOperationException("Unsupported binary operator: " + bin.NodeType); 
    } 

    throw new InvalidOperationException("Unsupported expression type: " + expression.GetType().Name); 
} 
+0

très gentil copain je l'ai fait une méthode comme ça, mais il m'a toujours donné exception, grâce Timwi – Stacker

Questions connexes