如何进行涉及用作标志的枚举的 HQL 或 Criteria 搜索(首选后者)。换句话说,我有一个存储某种标志的持久枚举属性。我想查询设置了这些标志之一的所有记录。当然,使用 Eq 是行不通的,因为只有当那是唯一的标志集时才会如此。
使用 Criteria API 解决这个问题是最好的,但如果这只能使用 HQL 也很好。
如何进行涉及用作标志的枚举的 HQL 或 Criteria 搜索(首选后者)。换句话说,我有一个存储某种标志的持久枚举属性。我想查询设置了这些标志之一的所有记录。当然,使用 Eq 是行不通的,因为只有当那是唯一的标志集时才会如此。
使用 Criteria API 解决这个问题是最好的,但如果这只能使用 HQL 也很好。
以下是使用条件 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 的行(不包括其他所有内容)。您也应该能够将它与合取和析取一起使用。
HQL 很简单:
var matching = session.CreateQuery(@"
from MyEntity
where FlagsProperty & :flag = :flag
")
.SetParameter("flag", MyEnum.FlagValue)
.List<MyEntity>();
以下是我使用 Criteria 解决的方法:
Expression.Eq(
Projections.SqlProjection("({alias}." + propertyname + " & " +
((int)value).ToString() + ") as " + propertyname + "Result",
new[] { propertyname + "Result" },
new IType[] { NHibernateUtil.Int32 }
), value );
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))
)