我正在与NHibernate命名查询和PostgreSQL搏斗,但无法让它工作。我在PostgreSQL数据库中有一个函数:
create or replace function x(results refcursor, id_ bigint)
returns refcursor
as
$$
begin
open results for
select
id,
name,
number
from
table_name
where
id = id_;
return results;
end;
$$ language plpgsql;
然后我在NHibernate中进行了映射:
<sql-query name="SqlQueryForTesting">
<return-scalar column="id" type="long" />
<return-scalar column="name" type="string" />
<return-scalar column="number" type="string" />
<![CDATA[
begin;
select x('table_name_cursor', :id);
fetch all in table_name_cursor;
commit;
]]>
</sql-query>
最后制作了一个调用这个命名查询的方法。
public IList MethodForNamedQuery(int id)
{
var query = Session.GetNamedQuery("SqlQueryForTesting");
query.SetInt32("id", id);
return query.List();
}
问题是这段代码给了我一个错误。
System.IndexOutOfRangeException
Field not found
at Npgsql.NpgsqlRowDescription.FieldIndex(String fieldName)
at NHibernate.Driver.NHybridDataReader.GetOrdinal(String name)
at NHibernate.Type.NullableType.NullSafeGet(IDataReader rs, String name)
at NHibernate.Type.NullableType.NullSafeGet(IDataReader rs, String name, ISessionImplementor session, Object owner)
at NHibernate.Loader.Custom.CustomLoader.ScalarResultColumnProcessor.Extract(Object[] data, IDataReader resultSet, ISessionImplementor session)
at NHibernate.Loader.Custom.CustomLoader.ResultRowProcessor.BuildResultRow(Object[] data, IDataReader resultSet, Boolean hasTransformer, ISessionImplementor session)
at NHibernate.Loader.Custom.CustomLoader.GetResultColumnOrRow(Object[] row, IResultTransformer resultTransformer, IDataReader rs, ISessionImplementor session)
at NHibernate.Loader.Loader.GetRowFromResultSet(IDataReader resultSet, ISessionImplementor session, QueryParameters queryParameters, LockMode[] lockModeArray, EntityKey optionalObjectKey, IList hydratedObjects, EntityKey[] keys, Boolean returnProxies)
at NHibernate.Loader.Loader.DoQuery(ISessionImplementor session, QueryParameters queryParameters, Boolean returnProxies)
at NHibernate.Loader.Loader.DoQueryAndInitializeNonLazyCollections(ISessionImplementor session, QueryParameters queryParameters, Boolean returnProxies)
at NHibernate.Loader.Loader.DoList(ISessionImplementor session, QueryParameters queryParameters)
NHibernate.Exceptions.GenericADOException
could not execute query
[ begin;
select x('table_name_cursor', :p0);
fetch all in table_name_cursor;
commit; ]
Name:id - Value:2
如果我通过pgAdmin运行我的查询,它可以完美地运行并返回一行。所以我猜这个问题在映射的某个地方。有人可以说我的映射有什么问题吗?
答案 0 :(得分:0)
NHibernate不知道它是一个原生查询,因此它试图将其解释为常规NHibernate查询,它将通过映射实体进行搜索。
如果您可以将函数创建为存储过程,则可以定义命名查询,如this example:
<sql-query name="selectAllEmployments_SP">
<return alias="emp" class="Employment">
<return-property name="employee" column="EMPLOYEE"/>
<return-property name="employer" column="EMPLOYER"/>
<return-property name="startDate" column="STARTDATE"/>
<return-property name="endDate" column="ENDDATE"/>
<return-property name="regionCode" column="REGIONCODE"/>
<return-property name="id" column="EID"/>
<return-property name="salary">
<return-column name="VALUE"/>
<return-column name="CURRENCY"/>
</return-property>
</return>
exec selectAllEmployments
</sql-query>
答案 1 :(得分:0)
我猜id
是一个输入参数,但在您的查询中,它使用return-scalar
声明为输出参数。尝试将其更改为query-param
,看看它是否有效:
<query-param column="id" type="long" />