如何查询 NHibernate 中存储为枚举的标志

发布于 2024-09-01 04:21:26 字数 177 浏览 5 评论 0原文

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

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

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.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

爱格式化 2024-09-08 04:21:35

如果您要查询 2 个值,则需要查找 Expression.Or;如果您要查询 2 个以上的值,则需要查找 Expression.Disjunction

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

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))
)
东走西顾 2024-09-08 04:21:34

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

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

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 );
温馨耳语 2024-09-08 04:21:33

HQL 很简单:

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

HQL is easy:

var matching = session.CreateQuery(@"
                       from MyEntity
                       where FlagsProperty & :flag = :flag
                       ")
                      .SetParameter("flag", MyEnum.FlagValue)
                      .List<MyEntity>();
滴情不沾 2024-09-08 04:21:32

以下是如何使用标准 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, " & " );
    }
}

应该生成以下输出 where 子句:

 FROM _TABLE
 WHERE  (this_.Bar & 5 = 5)

应该为您提供设置了标志 Bar.A 和 Bar.C 的行(不包括其他所有内容)。您也应该能够将它与合取和析取一起使用。

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.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文