3

如何进行涉及用作标志的枚举的 HQL 或 Criteria 搜索(首选后者)。换句话说,我有一个存储某种标志的持久枚举属性。我想查询设置了这些标志之一的所有记录。当然,使用 Eq 是行不通的,因为只有当那是唯一的标志集时才会如此。

使用 Criteria API 解决这个问题是最好的,但如果这只能使用 HQL 也很好。

4

4 回答 4

12

以下是使用条件 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 的行(不包括其他所有内容)。您也应该能够将它与合取和析取一起使用。

于 2011-05-13T08:28:16.223 回答
6

HQL 很简单:

var matching = session.CreateQuery(@"
                       from MyEntity
                       where FlagsProperty & :flag = :flag
                       ")
                      .SetParameter("flag", MyEnum.FlagValue)
                      .List<MyEntity>();
于 2010-05-10T22:25:54.047 回答
3

以下是我使用 Criteria 解决的方法:

Expression.Eq(
  Projections.SqlProjection("({alias}." + propertyname + " & " + 
    ((int)value).ToString() + ") as " + propertyname + "Result",
    new[] { propertyname + "Result" },
    new IType[] { NHibernateUtil.Int32 }
  ), value );
于 2010-05-14T16:23:52.737 回答
-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))
)
于 2010-05-10T21:17:04.027 回答