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