5

Я пытаюсь использовать функцию SQL CONSTAINS для фильтрации некоторых данных в QueryOver API.Как использовать полнотекстовый поиск для любого свойства с QueryOver API

Основная проблема заключается в том, что я не могу использовать SqlFunction в том месте, где он не компилируется, потому что нужен ICriterion.

var result = Session.QueryOver<Individual>() 
    .Where(Projections.SqlFunction(
     "FullTextContains", NHibernateUtil.Boolean, 
     Projections.Property<Individual>(x => x.LastName), 
     Projections.Constant("something"))) 
     .List(); 

Я пытался сопоставить его с константой TRUE, но при выполнении запроса он генерирует ошибку синтаксиса, поскольку CONSTAINS функция не может быть использована с равным оператору.

var result = Session.QueryOver<Individual>() 
    .Where(Restrictions.Eq(Projections.SqlFunction(
     "FullTextContains", NHibernateUtil.Boolean, 
     Projections.Property<Individual>(p => p.LastName), 
     Projections.Constant("something")), true)) 
     .List(); 

Как я могу использовать функцию булево SQL непосредственно в том, где выражение QueryOver API?

ответ

3

Это, как я нашел, как использовать его:

var projection = Projections.SqlFunction("FullTextContains", 
    NHibernateUtil.Boolean, 
    Projections.Property<Individual>(x => x.LastName), 
    Projections.Constant("something")); 

var result = Session.QueryOver<Individual>() 
    .Where(new ProjectionAsCriterion(projection)) 
    .List(); 

Чтобы использовать IProjection как ICriterion я создать свою собственную реализацию на основе SimpleExpression класса от проекта NHibernate.

public class ProjectionAsCriterion : AbstractCriterion 
{ 
    private readonly IProjection _projection; 

    public ProjectionAsCriterion(IProjection projection) 
    { 
     _projection = projection; 
    } 

    public override SqlString ToSqlString(ICriteria criteria, ICriteriaQuery criteriaQuery, 
     IDictionary<string, IFilter> enabledFilters) 
    { 
     var columnNames = CriterionUtil.GetColumnNamesForSimpleExpression(
      null, _projection, criteriaQuery, criteria, enabledFilters, this, string.Empty); 

     var sqlBuilder = new SqlStringBuilder(4 * columnNames.Length); 

     for (int i = 0; i < columnNames.Length; i++) 
     { 
      if (i > 0) 
      { 
       sqlBuilder.Add(" and "); 
      } 

      sqlBuilder.Add(columnNames[i]); 
     } 
     return sqlBuilder.ToSqlString(); 
    } 

    public override TypedValue[] GetTypedValues(ICriteria criteria, ICriteriaQuery criteriaQuery) 
    { 
     var typedValues = new List<TypedValue>(); 

     if (_projection != null) 
     { 
      typedValues.AddRange(_projection.GetTypedValues(criteria, criteriaQuery)); 
     } 
     typedValues.Add(GetParameterTypedValue(criteria, criteriaQuery)); 

     return typedValues.ToArray(); 
    } 

    private TypedValue GetParameterTypedValue(ICriteria criteria, ICriteriaQuery criteriaQuery) 
    { 
     return CriterionUtil.GetTypedValues(criteriaQuery, criteria, _projection, null).Single(); 
    } 

    public override IProjection[] GetProjections() 
    { 
     return new[] { _projection }; 
    } 

    public override string ToString() 
    { 
     return _projection.ToString(); 
    } 
}