2009-12-02 53 views
5

時CriteriaQuery中如何轉換這成CriteraQuery:HQL使用位運算符

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

回答

1

不喜歡的東西是前一陣子。

嘗試類似這樣的東西。

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做。

問候

14

這裏是你如何能與標準的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的行(不包括其他所有內容)。您應該能夠將它與連接和分離一起使用。

+0

好主意,我會添加一個方法'NotSet(..)'這應該導致'(this_.Bar&5 = 0)'使它完成 – Holly 2015-12-17 10:49:12