HQL в CriteriaQuery при использовании побитовых операторов - PullRequest
5 голосов
/ 02 декабря 2009

Как мне преобразовать это в CriteraQuery:

select n
from TagRegistration t
join t.Tag n
where t.Status & :status > 0
order by count(t.ID) desc
       , n.Name asc

Ответы [ 2 ]

14 голосов
/ 13 мая 2011

Вот как это можно сделать с помощью API критериев:

[Flags]
enum Bar{
   A = 0x01,
   B = 0x02,
   C = 0x04
}

var criteria = this.Session.CreateCriteria<Foo>()
            .Add( BitwiseFlags.IsSet( "Bar", Bar.A | Bar.C ) );

с помощью:

public class BitwiseFlags : LogicalExpression
{
    private BitwiseFlags( string propertyName, object value, string op ) :
        base( new SimpleExpression( propertyName, value, op ),
        Expression.Sql( "?", value, NHibernateUtil.Enum( value.GetType() ) ) )
    {
    }

    protected override string Op
    {
        get { return "="; }
    }

    public static BitwiseFlags IsSet(string propertyName, Enum flags)
    {
        return new BitwiseFlags( propertyName, flags, " & " );
    }
}

должен сгенерировать следующий вывод where:

 FROM _TABLE
 WHERE  (this_.Bar & 5 = 5)

, который должен давать вам строки с установленными флагами Bar.A и Bar.C (исключая все остальное) Вы должны быть в состоянии использовать это также с соединением и дизъюнкцией.

1 голос
/ 05 декабря 2009

Сделал что-то подобное некоторое время назад.

Попробуйте что-то вроде этого.

PropertyProjection projection = Projections.Property("t.ID");
PropertyProjection property = Projections.Property("n.Namn");
ICriteria criteria = session.CreateCriteria<TagRegistration>("t")
                .CreateCriteria("Tag","n")
                .Add(
                        Restrictions.Gt(
                            Projections.SqlProjection("({alias}.ID & 3) as bitWiseResult", new[] { "bitWiseResult" }, new IType[] { NHibernateUtil.Int32 })
                        , 0)
                     )
                .AddOrder(Order.Desc(Projections.Count(projection)))
                .AddOrder(Order.Asc(property))
                .SetProjection(Projections.GroupProperty(projection), Projections.GroupProperty(property))

Обратите внимание на эту часть {псевдоним} .ID & 3), где я вставил значение напрямую, что не очень хорошо, но это работает:

Вы могли бы сделать это лучше, если посмотрите на тестовый проект NHibernate. NHibernate / Критерии / AddNumberProjection.cs

Но вам нужно выполнить подзапрос, чтобы вернуть полностью инициализированный тег Я думаю, что этот запрос лучше сделать в Hql.

Привет

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...