2010-05-10 78 views
3

如何執行涉及用作標誌的枚舉的HQL或Criteria搜索(後者是首選)。換句話說,我有一個持久的枚舉屬性,存儲某種標誌。我想要查詢所有設置了這些標誌之一的記錄。使用Eq當然不會起作用,因爲只有這是唯一的標誌纔會是真的。如何在NHibernate中查詢存儲爲枚舉的標誌

使用Criteria API解決這個問題將是最好的,但是如果這隻能使用HQL來實現,那也不錯。

回答

12

下面是如何與th Ë標準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

如何使用QueryOver完成此操作? – davymartu 2013-05-30 09:52:25

+1

在https://github.com/AndreasJilvero/NHibernate.Bitwise找到完美的QueryOver解決方案。非常感謝發現可以添加到現有的QueryOver查詢,而不是將其切換。乾淨而乾淨的實施。 – Ted 2015-06-14 02:33:29

-2

您正在尋找Expression.Or如果要查詢2倍的值或者Expression.Disjunction如果你要查詢超過2個值:

criteria.Add(
    Expression.Disjunction() 
    .Add(Expression.Eq("property", value1)) 
    .Add(Expression.Eq("property", value2)) 
    .Add(Expression.Eq("property", value3)) 
) 
+2

我不認爲這將適用於我看到的基於標誌的枚舉 – SztupY 2010-05-10 21:39:24

+0

。那麼錯誤答案的好例子。 – 2010-05-11 04:54:57

6

HQL很簡單:

var matching = session.CreateQuery(@" 
         from MyEntity 
         where FlagsProperty & :flag = :flag 
         ") 
         .SetParameter("flag", MyEnum.FlagValue) 
         .List<MyEntity>(); 
+0

有沒有一種使用NHibernate LINQ實現相同的方法?我試圖做這樣的事情....在Session.Linq ()其中(obj.FlagsProperty&標誌)==(標誌)選擇OBJ obj)從obj。 ...其中標誌是參數,但它是拋出異常「System.NullReferenceException:對象引用未設置爲對象的實例」 – nabeelfarid 2010-07-12 16:28:07

+0

史蒂夫剛纔在論壇中回答了這個問題,刪除了我之前的回覆 – 2010-07-12 18:52:12

+0

是的,這是......謝謝 – nabeelfarid 2010-07-13 08:34:49

3

這是我如何解決使用標準:

Expression.Eq(
    Projections.SqlProjection("({alias}." + propertyname + " & " + 
    ((int)value).ToString() + ") as " + propertyname + "Result", 
    new[] { propertyname + "Result" }, 
    new IType[] { NHibernateUtil.Int32 } 
), value);