I need a little help on this. I'm trying to use a table-valued function in a select, but I got the error that this is not mapped.
dbo.FnListEvnt is not mapped [from dbo.FnListEvnt(:dt, :id, :code) ]
Function
CREATE FUNCTION [dbo].[FnListEvnt]
(@DT DATETIME, @ID INT, @CODE VARCHAR (4))
RETURNS
@RESULTADO TABLE (
ID INT ,
DT_INIC DATETIME ,
DT_TMNO DATETIME ,
CD_EVNT VARCHAR (5) )
AS
BEGIN
Custom Dialect (this is defined in .config )
public class CustomFunctionsMsSql2008Dialect : MsSql2008Dialect
{
public CustomFunctionsMsSql2008Dialect()
{
RegisterFunction("dbo.FnListEvnt", new StandardSQLFunction("dbo.FnListEvnt", null));
}
}
Query
var query = Session.CreateQuery("from dbo.FnListEvnt(:dt, :id, :code) ")
.SetDateTime("dt", dt)
.SetInt32("id", id)
.SetString("code", code);
You won't be able to use RegisterFunction
for this. That's for registering scalar functions.
However, you can create a named query and execute that instead. That involves a few steps though:
Create the named query XML file. This must end in *.hbm.xml
. I find it useful to keep the name of the named query, the function, and the XML file all the same, but that's not required. Here's an example of what the XML file could look like:
<?xml version="1.0" encoding="utf-8" ?>
<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2">
<sql-query name="FnListEvnt">
<return-scalar column="ID" type="integer"/>
<return-scalar column="DT_INIC" type="DateTime"/>
<return-scalar column="DT_TMNO" type="DateTime"/>
<return-scalar column="CD_EVNT" type="string" />
select
*
from
dbo.[FnListEvnt](:dt, :id, :code);
</sql-query>
</hibernate-mapping>
If your query returns a mapped class (unmapped classes will not work), you can use return-class
instead of a list of return-scalar
elements.
Create a result class (unless you're returning a mapped class). Note that your class' property names must match the column names of the resultset:
public class Result
{
public int ID { get; set; }
public DateTime DT_TMNO { get; set; }
public DateTime DT_INIC { get; set; }
public string CD_EVNT { get; set; }
}
Use GetNamedQuery
to create the query, then set the parameters and execute the query:
var results = session.GetNamedQuery("FnListEvnt")
.SetDateTime("dt", DateTime.Now)
.SetInt32("id", 4)
.SetString("code", "code")
.SetResultTransformer(Transformers.AliasToBean<Result>())
.List<Result>();
That's really it. You should now be able to use your TVF with NHibernate.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With