在HQL查询中混合使用某些SQL

时间:2014-11-27 16:54:40

标签: sql oracle nhibernate hql

我正在从数据库中读取元数据并基于此构建查询。

出于性能原因,我们的DBA创建了一个选择特定数据的功能。它看起来像这样:

SELECT tab.id, packName.fnName(p1 => tab.id, p2 => 5), packName.fnName(p1 => tab.id, p2 => 7)
FROM table tab

(表格在NHibernate中映射)

是否可以将这种选择添加到HQL查询中?我使用的是Transformers.AliasToBean,所以fnName()的结果不是问题。

2 个答案:

答案 0 :(得分:1)

似乎你可以使用公式来实现这一点,

<property name="FnName1" formula="(SELECT packName.fnName(p1 => tab.id, p2 => 5) FROM table tab)"/>
<property name="FnName2" formula="(SELECT packName.fnName(p1 => tab.id, p2 => 7) FROM table tab)"/>

参考:http://ayende.com/blog/3936/nhibernate-mapping-property

答案 1 :(得分:1)

您应该可以通过创建自定义方言并使用该方言注册您的功能来实现此目的:

public class MyCustomDialect : Oracle10gDialect // or whatever version you're using
{
    public MyCustomDialect()
    {
        RegisterFunction(
            "packname",
            new SQLFunctionTemplate(
                NHibernateUtil.String, "packName.fnName(p1 => ?1, p2 => ?2)"));
    }
}

然后,您必须配置NHibernate以使用您的自定义方言(您已经在某处执行此操作,通过hibernate.cfg.xml文件中的XML或配置代码)。只需用这个自定义方言替换当前方言。

现在你应该可以在HQL中调用你的函数了:

session.CreateQuery(
        "select tab.id, packname(tab.id, 5), packname(tab.id, 7) from table tab")
    .TransformUsing(....);

哪个应生成如下所示的SQL:

select
    tab.id
    packName.fnName(p1 => tab0_.id, p2 => 5) as col_0_0_,
    packName.fnName(p1 => tab0_.id, p2 => 7) as col_0_1_
from
    Table tab0_

请注意,如果您希望将此函数与Criteria,QueryOver或LINQ-to-NHibernate一起使用,那么实现这一目标所需的步骤并不多。