无法使用nHibernate执行存储过程

3
首先,很抱歉在有几个理论上解释这个问题的资源存在的情况下再次提出这个问题。我在问题底部列出了我使用的参考资料,希望它们能帮助其他人。
我正在尝试在Oracle 11数据库上执行一个简单的存储过程。我的意图是通过SYS_REFCURSOR返回的数据创建一个List{T}对象。但是,当我尝试创建一个NHibernate会话对象时,我收到以下错误消息: {"Errors in named queries: {GET_COLLATERAL}"}
以下是我的映射。命名空间、架构、程序集、查询名称都拼写正确。文件名为GetCollateral.hbm.xml,并标记为嵌入式资源。
<?xml version="1.0" encoding="utf-8" ?>
 <hibernate-mapping xmlns="urn:nhibernate-mapping-2.2"
                   assembly="Poolman" namespace="Poolman.Entities" schema="poolman_own">
  <sql-query name="GET_COLLATERAL" callable="true">
    <return class="Poolman.Entities.IDNamePair">
      <return-property name="ID" column="sort_order"></return-property>
      <return-property name="Name" column="collateral"></return-property>
    </return>
    {GET_COLLATERAL(?)}
  </sql-query>
</hibernate-mapping>

经过一番疑难杂症的排查,我成功创建了一个会话对象,方法是移除映射中的返回元素,如下所示。显然,此处存在问题,但我不知道具体是什么。
<?xml version="1.0" encoding="utf-8" ?>
<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2"
                   assembly="Poolman" namespace="Poolman.Entities" schema="poolman_own">
  <sql-query name="GET_COLLATERAL" callable="true">
    {GET_COLLATERAL(?)}
  </sql-query>
</hibernate-mapping>

我不希望没有返回映射就得到结果集,但使用上述映射允许nhibernate创建其会话对象并尝试执行查询。然而,nHibernate无法正确获取它的参数。我收到了这个错误信息:
{"预期位置参数计数:1,实际参数:[] [{GET_COLLATERAL(?)}]"}
我已经尝试过:
CALL GET_COLLATERAL()
BEGIN GET_COLLATERAL(); END;
以上内容包含在CDATA中
这是我的存储过程:
create or replace
PROCEDURE GET_COLLATERAL(p_cursor OUT SYS_REFCURSOR)
IS

BEGIN
  OPEN p_cursor for
  SELECT collateral, sort_order
  FROM
  (
    -- Long query omitted.  The query executes when pasted into a command window.

  )  ORDER BY sort_order ;

END;

这是我的实体类。这个类并不映射到任何一个表,但我仍然尝试创建了一个映射。

namespace Poolman.Entities
{
    public class IDNamePair
    {
        public virtual int ID { get; set; }
        public virtual string Name { get; set; }
    }
}



<?xml version="1.0" encoding="utf-8" ?>
<hibernate-mapping assembly="Poolman"
                   namespace="Poolman.Entities"
                   schema="poolman_own"
                  xmlns="urn:nhibernate-mapping-2.2">
  <class name="IDNamePair" table="x">
    <id></id>
    <property name="ID" column="sort_order"/>
    <property name="Name" column="collateral"/>
  </class>
</hibernate-mapping>

这是我用来调用查询的代码:

以下是我用来调用查询的代码:

public List<Entities.IDNamePair> GetCollateral()
        {
            IQuery query = (IQuery)Session.GetNamedQuery("GET_COLLATERAL");
            List<Entities.IDNamePair> list = new List<Entities.IDNamePair>();
            System.Collections.IList result = query.List();
            list = result.OfType<Entities.IDNamePair>().ToList();
            return list;
        }

我非常感激您的帮助。我陷入了困境。

以下是我找到的其他资源链接,但都不能帮助我:

Oracle存储过程、SYS_REFCURSOR和NHibernate

http://www.techonthenet.com/oracle/questions/cursor1.php


为什么你想要用NHibernate来做这个,当你可以很容易地使用ADO完成它呢? - TedOnTheNet
我自己在使用序数参数方面并没有太好的运气,你尝试过使用命名参数吗?http://hoolihan.net/blog-tim/2011/06/23/nh-named-sql-queries-with-parameters/ - Mark Broadhurst
1个回答

0

对于这个问题,可能有两个考虑:

  • 首先,没有输入参数的存储过程不需要使用参数进行调用,因此像这个问题评论中所说的calling sp with out ref cursor,可以通过这种方式调用SP:{ call GET_COLLATERAL }
  • 其次,要使用“未映射”类作为结果集,您应该告诉nhibernate关于那个“未映射”类,所以请尝试在映射文件的顶部添加<import class="FullClassName" rename="ClassNameMayBeRenamed"/>

因此,这可能是这个SP的映射:

 ....
 <import class="Poolman.Entities.IDNamePair" />
 ....
 <sql-query name="GET_COLLATERAL" callable="true">
    <return class="Poolman.Entities.IDNamePair">
      <return-property name="ID" column="sort_order"></return-property>
      <return-property name="Name" column="collateral"></return-property>
    </return>
    { call GET_COLLATERAL}
 </sql-query>

调用代码可以是一个简单的代码通过NHibernate调用SP。 我希望这可以成为你的解决方案。如果我错了,请让我知道

问候


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接