Проблема решена, хотя кажется очевидным, что NHibernate не хочет, чтобы вы использовали хранимые процедуры. Я публикую это, чтобы помочь другим с той же проблемой, так как эту информацию было нелегко найти!
Первоначальный блог, который помог с этим, был здесь, хотя этот пример отображал результат обратно в стандартный объект - отображение таблицы (что может быть тем, что вы хотите). Я хотел сопоставить результат обратно с пользовательским объектом, который не имел табличного представления в базе данных:
http://forums.asp.net/t/1407518.aspx/1
Итак, я создал класс домена для хранения результата хранимой процедуры.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace MyProj.DataEntityTracker.Domain.Entities
{
public class DemoCustomSprocObj
{
public virtual Guid Guid { get; set; }
public virtual int ID { get; set; }
public virtual string Name { get; set; }
}
}
Этому классу не обязательно иметь соответствующую таблицу на сервере SQL, хотя я обнаружил, что определение класса нужно создавать (без атрибута таблицы), чтобы избежать «NHibernate.MappingException: No persister for:» type ошибки.
Обратите внимание также, что классу домена, который создается для хранения результата хранимой процедуры, необходимо поле идентификатора, и это должно быть возвращено из базы данных. В этом случае я возвратил NEWID () из SQL Server и настроил класс сопоставления для использования генератора GUID для поля идентификатора.
CREATE PROCEDURE usp_DemoCustomSproc
@TrackedEntityID INT
AS
SET NOCOUNT ON
BEGIN
SELECT NEWID() AS [Guid],
ID ,
Name
FROM TrackedEntityProperties AS tep
WHERE TrackedEntityID = @TrackedEntityID
END
И класс отображения:
<?xml version="1.0" encoding="utf-8" ?>
<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2"
assembly="MyProj.DataEntityTracker.Domain"
namespace="MyProj.DataEntityTracker.Domain.Entities">
<!-- This mapping does not use a table, rather it exists to
allow the mapping of a stored procedure result back to a domain object.
Note the use of the GUID. An ID must be present and returned by the stored
procedure result, otherwise the object will not work with NHibernate.
Note also the absence of a table in the class tag. No table exists in
the database, but the mapping must exist to avoid "No persiter" errors.
Arguments are passed with the :Arg syntax.
It seems that NHibernate was not designed for use with stored procedures,
though it may be useful to be able to use them in some situations. This
is a means of doing so.
-->
<class name="DemoCustomSprocObj">
<id name="Guid" type="guid" unsaved-value="00000000-0000-0000-0000-000000000000">
<generator class="guid"></generator>
</id>
<property name="ID" />
<property name="Name" />
</class>
<sql-query name="usp_DemoCustomSproc">
<return alias="usp_DemoCustomSproc" class="DemoCustomSprocObj">
<return-property name="Guid" column="Guid" />
<return-property name="ID" column="ID" />
<return-property name="Name" column="Name" />
</return>
exec usp_DemoCustomSproc :TrackedEntityID
</sql-query>
</hibernate-mapping>