2016-01-05 1 views
2

Im пытается создать несколько фильтров для моих коллекций.Динамическое построение соединения для Nhibernate QueryOver в C#

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

Я сказал, конечно при вызове линии conjunction.Add выдает ошибку «переменная„х“типа„Foo“ссылается из сферы„“, но он не определен NHibernate queryOver».

Как я могу построить соединение или выражение, которое может быть принято queryOver.Where()?

Я ищу довольно универсальное решение для добавления фильтрации в QueryOvers, любое предложение?

+0

У меня нет времени сейчас, чтобы создать полный ответ, но [это сообщение] (Http: //blog.andrewawhitaker .com/blog/2015/05/31/queryover-series-part-10-combining-criteria-queryover /) (отказ от ответственности: это мой личный блог) может помочь. –

+0

Уже красный, что: D Я решил изменить свой подход и просто создать expresion builder с использованием основных выражений, поскольку нет возможности использовать PropertyInfo в том, как я представил выше. Thx для вашего внимания Эндрю. – PabloPC

+0

Хорошо. Если вы это выясните, было бы полезно разместить ответ на свой вопрос здесь, чтобы другие могли его найти –

ответ

0

я ходить с помощью критерия ALD построения простых выражений, все выглядит следующим образом:

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

Существует какая-то особая логика критериев струнных зданий, но его анали и довольно просто, как все остальное. Вы можете построить конъюнкции, дизъюнкции и вернуть их в ICriteria, как, что, например:

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

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

PS Filter.Member струнный Filter.Value является объектом и оператор перечисления