I’ve got an application witch uses NHibernate as an ORM. I have one persistent class:
public class Match : IEntity
{
public virtual int ID { get; set; }
public virtual string Word { get; set; }
public virtual int WordIntervalBeginning { get; set; }
public virtual int WordIntervalEnding { get; set; }
}
and I have an SQL function on the server side:
CREATE FUNCTION ftMatchTest
( )
RETURNS TABLE
AS
RETURN
(
SELECT mt1.*, mt2.*,
CASE WHEN mt1.Word = mt2.Word THEN 1 ELSE 0 END AS sc
FROM
dbo.tMatchesTest mt1, dbo.tMatchesTest mt2
)
I want to be able to call this function and map the result from it into the following class
public class FResult
{
public Match Match1 { get; set; }
public Match Match2 { get; set; }
public int sc { get; set; }
}
Is it possible to do it with NHibernate 3.0? Is it possible to do it with FluentNHibernate?
Thanks in advance!
UPDATED
I map Match class into tMatchesTest table.
Structure of tMatchesTest table is:
CREATE TABLE [dbo].[tMatchesTest](
[ID] [int] IDENTITY(1,1) NOT NULL,
[Word] [varchar](50) NOT NULL,
[WordIntervalBeginning] [int] NOT NULL,
[WordIntervalEnding] [int] NOT NULL,
CONSTRAINT [PK_tMatchesTest] PRIMARY KEY CLUSTERED
(
[ID] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]
UPDATED2
The solution I found on my own:
1. Create named query like this
<?xml version="1.0" encoding="utf-8" ?>
<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2"
namespace=" ConsoleApplication8.Domain.Entities"
assembly="ConsoleApplication8">
<resultset name="fresult-resset">
<return alias="Match1" class="Match"/>
<return alias="Match2" class="Match"/>
<return-scalar column="sc" type="int"/>
</resultset>
<sql-query name="getfresult" resultset-ref="fresult-resset">
SELECT {Match1.*}, {Match2.*},
CASE WHEN Match1.Word = Match2.Word THEN 1 ELSE 0 END sc
FROM dbo.tMatchesTest Match1, dbo.tMatchesTest Match2
</sql-query>
</hibernate-mapping>
and execute the query like this:
Session.GetNamedQuery("getfresult")
.SetResultTransformer(new AliasToBeanResultTransformer(typeof(FResult)))
.List<FResult>();
This is the shortest and simples way I found so far to perform the task.
IResultTransformer is used to transform query results into a application-visible types.
Also, mapping the SQL function call as a named SQL query will give cleaner code.
Since we have a multi-table result, AliasToBeanResultTransformer is not directly usable. Instead we will subclass it and convert the result to the desired type.