我有一个映射在Fluent NHibernate中的表 . 此表必须连接到ID上的另一个表,但还必须根据一组常量值过滤该表上的连接值 . 考虑以下SQL:
SELECT *
FROM
Table1
INNER JOIN
Table2 ON
Table1.Table2Id = Table2.Id
AND Table2.Category = 'A constant expression'
AND Table2.Language = 'A constant expression'
我对Table1的流畅映射目前看起来像这样:
References(a => a.Table2).Nullable().Columns("Table2Id").ReadOnly();
如何实现常量表达式?
3 回答
我注意到你的映射指定Nullable并且没有急切的提取(默认情况下它将是延迟加载的) . 因此,如果您确实想要生成您在评论中显示的sql,则无法使用简单的
session.Get<Table1>()
来执行此操作 . 即使你改变了映射,它就像这样:您很可能最终在输出的sql中使用左外连接 . 你可以使用内连接强制获取(没有下载任何额外的NHibernate插件)的唯一方法是使用
session.QueryOver
(你也可以使用session.Query和NHibernate linq扩展) . 如果是这种情况,那么您也可以在QueryOver查询中指定您的常量集 .我认为Russ显示的ApplyFilter方法确实使模型检索变得更加简单,并且它非常适合代码重用(如果你有其他表和类别和语言),但由于你的表引用是可以为空的引用,你必须无论如何都要使用查询 . 也许QueryOver与过滤器的组合将是最好的(假设您可以获得更流畅的NHibernate的更高版本)
听起来你可以使用过滤器来做到这一点 .
首先,您需要定义过滤器类型
EDITED: As per comments, there is no .ApplyFilter<TFilter>() on References(), so have updated with what I believe is the way to do it with filters
过滤器需要应用于流畅的映射
最后,当您打开会话时,您需要启用过滤器
如果您正在使用
ICurrentSessionContext
的实现并且应始终应用过滤器,则可以启用从调用ICurrentSessionContext.CurrentSession()
返回的会话中的过滤器 .现在,当查询
Table1
时,为了激活Table2
的过滤器,需要指示NHibernate加入引用的Table2
;你可以这样做Fetch(t => t.Table2).Eager
JoinQueryOver(t => t.Table2)
(以及类似的加入策略)在没有指示NHibernate进行连接的情况下,默认情况下引用将被延迟加载,因此过滤器将不会应用于查询中 . 缺点是
Table2
将被急切提取,但我不知道如何应用过滤器 . 以下查询结果在SQL中类似于
这类似于您在问题中的SQL .
您可能需要查看
Formula(string formula)
,您可以在其中提供纯SQL . 如果在映射级别上过滤数据是个好主意是另一个问题恕我直言......作为一个例子看看here .