0

可能重复:
如何查询在 NHibernate 中存储为枚举的标志

我有三张桌子 - Recipient, Message,MessageType

消息类型如下所示:

| ID | Description  |
|====|==============|
|  1 | JobAlert     |
|  2 | Newsletter   |
|  3 | SpecialOffer |
|  4 | Survey       |

Recipient包含用作位域的整数列;收件人可以选择他们想要接收的消息类型;如果收件人想要接收时事通讯和特别优惠,我们会将其位域设置为(2 ^ 2) | (2 ^ 3)

Message包含对MessageTypeId和计算列的引用,MessageTypeBitFlag定义为POWER(2, MessageTypeId)

我用 SQL 表示的查询类似于:

SELECT * FROM Message, Recipient
  WHERE Recipient.MessageTypeBitField & Message.MessageTypeBitFlag > 0

通过对 bitfield 和 bitflag 列进行按位与操作,很容易只选择特定收件人感兴趣的消息。

问题是,我不是在 SQL 中执行此操作 - 我需要将此作为附加选项添加到基于 NHibernate Criteria API 构建的相当丰富的系统中。

有没有办法通过 NHibernate API 来表达这个标准 - 使用 API 或通过向现有标准添加 SQL/HQL 子句?

4

1 回答 1

0

好的,这是基于Firo提交的链接帖子的具体实现,因为我必须对其进行一些调整才能使其工作:

/// <summary>An NHibernate criterion that does bitwise comparison to match a bit flag against a bitmask.</summary>
public class BitMask : LogicalExpression {
    private BitMask(string propertyName, object value, string op) :
        base(new SimpleExpression(propertyName, value, op), Expression.Sql("?", 0, NHibernateUtil.Int64)) {
    }

    protected override string Op {
        get { return ">"; }
    }
    /// <summary>Create a bitwise filter criterion - i.e. one that will be satisified if <code><paramref name="propertyName"/> &amp; <paramref name="bits"/> &gt; 0</code></summary>
    public static BitMask Matches(string propertyName, long bits) {
        return new BitMask(propertyName, bits, " & ");
    }
}

然后通过 Criteria API 使用它,如下所示:

public IEnumerable<Message> GetMessagesForRecipient(Recipient r) {
    var messages = session.CreateCriteria<Message>()
        .Add(BitMask.Matches("MessageTypeBitFlag ", r.MessageTypeBitField))
        .List<Message>();
    return(messages);
}
于 2012-02-17T12:54:52.320 回答