5

J'essaie d'utiliser la fonction SQL CONSTAINS pour filtrer certaines données sur l'API QueryOver.Comment utiliser la recherche de texte intégral pour une propriété avec l'API QueryOver

Le problème principal est que je ne peux pas utiliser SqlFunction dans la clause where, il ne compile pas, car un ICriterion est nécessaire.

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

J'ai essayé de le faire correspondre à une constante TRUE, mais lorsque la requête est exécutée, il génère une erreur de syntaxe, car la fonction CONSTAINS ne peut pas être utilisé avec l'opérateur =.

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

Comment puis-je utiliser une fonction SQL booléenne directement où l'expression sur l'API de QueryOver?

Répondre

3

Voici comment je l'ai trouvé comment l'utiliser:

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

Pour utiliser un IProjection comme ICriterion je crée ma propre implémentation basée sur SimpleExpression classe du projet 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(); 
    } 
}