Деревья экспрессии в NHibernate - PullRequest
2 голосов
/ 08 августа 2010

У меня есть метод, который имеет эту подпись

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

Я использую для передачи лямбда-выражений и ограничения поиска в nhibernate путем извлечения данных из expressiontree.

Поэтому, когда пользователь класса передает что-тонапример:

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

Я получаю эту структуру для чтения из дерева выражений, таким образом, у меня есть полный интеллектуальный способ предоставить критерии поиска

Другими словами: мне нужно передать критерии поиска вслой доступа к данным (Nhibernate)

Поэтому мне нужно извлечь критерии из дерева выражений, а затем передать его в спящий режим n, например:

c=>c.fullname = "John" 

Я извлеку следующую информацию из дерева выражений:

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

и затем передайте эту информацию в nhibernate следующим образом:

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

В любом случае проблема заключается в том, что действительно трудно прочитать из expressiontree, поэтому мне было интересно, если у вас, ребята, естьлюбой простой способ, может быть, перебирать дерево выражений для извлечения данных, или, может быть, у вас есть какой-то код для извлечения данных из ExpressionTreе.

1 Ответ

6 голосов
/ 08 августа 2010

Вот некоторый код, который извлекает информацию, которую вы упомянули.Я уверен, что вы можете расширить это, чтобы включить дополнительную информацию, которую вы, возможно, ищете.

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