3

Im trying to build somewhat of filter builder for my collections.

public static NHibernate.Criterion.Conjunction CreateConjunction<T>(this IEnumerable<FilterDescriptor> _filters)
        {
            NHibernate.Criterion.Conjunction conjunction = new NHibernate.Criterion.Conjunction();

            foreach (var filter in _filters)
            {
                PropertyInfo propertyInfoObj = typeof(T).GetProperty(filter.Member);
                conjunction.Add<T>(x => propertyInfoObj.GetValue(x, null) == filter.Value);
            }

            return conjunction;
        }

I can said of course when invoking line conjunction.Add throws an error 'variable 'x' of type 'Foo' referenced from scope '', but it is not defined nhibernate queryOver'.

How can I build conjunction or expression that can be accepted by queryOver.Where() ?

I'm looking for rather universal solution for adding filtering to my QueryOvers, any suggestion ?

PabloPC
  • 41
  • 4
  • I don't have time right now to create a complete answer but [this post](http://blog.andrewawhitaker.com/blog/2015/05/31/queryover-series-part-10-combining-criteria-and-queryover/) (disclaimer: This is my personal blog) might help. – Andrew Whitaker Jan 05 '16 at 14:31
  • Already red that :D I decided to change my approach and just create expresion builder with use of basic Expressions since there is no option of using PropertyInfo in the way i presented above. Thx for your concern Andrew. – PabloPC Jan 05 '16 at 14:50
  • Okay--If you do figure it out it would definitely be helpful to post an answer to your question here so that others can find it – Andrew Whitaker Jan 05 '16 at 14:55

1 Answers1

0

I did walk around using criterion ald building simple expressions, all looks like that:

public static void AddFilterCriteria<T>(this NHibernate.IQueryOver<T,T> _this, IEnumerable<Filter> _filters)
{
    foreach (var filter in _filters)
    {
        _this.And(GetCriterion(filter));
    }
}

public static NHibernate.Criterion.ICriterion GetCriterion(Filter _filter)
{
    if (_filter.Value is string)
    {
        return GetCriterionForString(_filter);
    }

    switch (_filter.Operator)
    {
        case eFilterOperator.IsEqualTo:
            {
                return NHibernate.Criterion.Expression.Eq(_filter.Member, _filter.Value);
            }
        case eFilterOperator.IsNotEqualTo:
            {
                return NHibernate.Criterion.Expression.Not(NHibernate.Criterion.Expression.Eq(_filter.Member, _filter.Value));
            }
        case eFilterOperator.IsGreaterThan:
            {
                return NHibernate.Criterion.Expression.Gt(_filter.Member, _filter.Value);
            }
        case eFilterOperator.IsGreaterThanOrEqualTo:
            {
                return NHibernate.Criterion.Expression.Ge(_filter.Member, _filter.Value);
            }
        case eFilterOperator.IsLessThan:
            {
                return NHibernate.Criterion.Expression.Lt(_filter.Member, _filter.Value);
            }
        case eFilterOperator.IsLessThanOrEqualTo:
            {
                return NHibernate.Criterion.Expression.Le(_filter.Member, _filter.Value);
            }
        default:
            throw new InvalidOperationException();
    }
}

There is some special logic for string criteria building, but its analogic and pretty simple as rest of it. You can build conjunctions, disjunctions and return them as ICriteria like that for example:

case eFilterOperator.Contains:
                    {
                        NHibernate.Criterion.Conjunction conjunction = new NHibernate.Criterion.Conjunction();
                        conjunction.Add(NHibernate.Criterion.Expression.IsNotNull(_filter.Member)); 
                        conjunction.Add(NHibernate.Criterion.Expression.InsensitiveLike(_filter.Member, _filter.Value.ToString(), NHibernate.Criterion.MatchMode.Anywhere));
                        return conjunction;
                    }

Everything works fine and I dont need to read whole data from database before applying filters, what was my goal.

PS Filter.Member is string Filter.Value is object and operator is enum

PabloPC
  • 41
  • 4