问题
How to do either a HQL or a Criteria search (the latter is preferred) involving an enum that is used as flags. In other words, I have a persisted enum property that stores some kind of flags. I want to query all the records that have one of these flags set. Using Eq won't work of course because that will only be true, if that is the only flag set.
Solving this using the Criteria API would be the best, but if this is only doable using HQL that is good too.
回答1:
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.
回答2:
HQL is easy:
var matching = session.CreateQuery(@"
from MyEntity
where FlagsProperty & :flag = :flag
")
.SetParameter("flag", MyEnum.FlagValue)
.List<MyEntity>();
回答3:
Here is how I solved using Criteria:
Expression.Eq(
Projections.SqlProjection("({alias}." + propertyname + " & " +
((int)value).ToString() + ") as " + propertyname + "Result",
new[] { propertyname + "Result" },
new IType[] { NHibernateUtil.Int32 }
), value );
回答4:
You are looking for Expression.Or
if you are querying 2 values or Expression.Disjunction
if you are querying for more than 2 values:
criteria.Add(
Expression.Disjunction()
.Add(Expression.Eq("property", value1))
.Add(Expression.Eq("property", value2))
.Add(Expression.Eq("property", value3))
)
来源:https://stackoverflow.com/questions/2805661/how-to-query-flags-stored-as-enum-in-nhibernate