Expression Trees in NHibernate
I have a method which have this signature
public static IList<T> GetBy<T>(System.Linq.Expressions.Expression<Func<T, bool>> expression)
I use to pass lambda expressions and make search restriction in nhibernate by retrieving data from expressiontree.
So when class user pass something like :
c => c.fullName == "John" && c.lastName == "Smith" && c.lastName != "" || c.fullName != "" && c.Age > 18
I get to read this structure from expression tree, that way I have a full intellisense way to provide searching criteria
In other words: I need to pass searching criteria to data开发者_如何学Python access layer (Nhibernate)
So I need to extract criteria from expression tree and then pass it to n hibernate by example :
c=>c.fullname = "John"
I will extract the following information from the expression tree :
propertyname = fullname , value = "John" , restrictiontype = "equality"
and then pass this info to nhibernate as following :
ICriteria crit = session.CreateCriteria(typeof(T));
crit.Add(Restrictions.Eq(propretyName, value));
IList<T> list = crit.Add(List<T>())
return list;
Any way the problem is it's really hard to read from expressiontree, so I was wondering if you guys have any easy way of maybe iterating inside expressiontree to pull data, or maybe you guys have some code to retrieve data from ExpressionTree.
Here is some code that retrieves the information you mentioned. I’m sure you can extend this to include additional information you might be looking for.
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);
}
精彩评论