Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

HQL to CriteriaQuery when using bitwise operators

Tags:

nhibernate

How do I convert this into a CriteraQuery:

select n
from TagRegistration t
join t.Tag n
where t.Status & :status > 0
order by count(t.ID) desc
       , n.Name asc
like image 482
dmonlord Avatar asked Dec 02 '09 19:12

dmonlord


2 Answers

Here's how you could do it with the criteria API:

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

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

using:

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, " & " );
    }
}

should generate the following output where clause:

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

which should give you rows that have flags Bar.A and Bar.C set (excluding everything else). You should be able to use it with conjunction and disjunction too.

like image 101
Brian Chavez Avatar answered Oct 23 '22 23:10

Brian Chavez


Did something like that a while ago.

Try something like this.

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

Note this part {alias}.ID & 3) where I inserted the value directly which isn't very good but it works :)

You could do it better if you look at the test project of NHibernate Nhibernate/Criteria/AddNumberProjection.cs

But you need to do a subQuery to return fully initialized Tag I think this query is better to do in Hql.

Regards

like image 37
cws Avatar answered Oct 23 '22 22:10

cws