Reputation: 407
I want to pass a collection of IDs (via table-valued parameter) to an NHibernate IQuery
select
statement to be used in a join:
In native SQL, I can do this (SQLSelectData below). Notice there is no :param
in the SqlCommand
sql:
public static bool SQLSelectData()
{
string conACME = System.Configuration.ConfigurationManager
.AppSettings["conACME"].ToString();
DataTable tblBusUnit = new DataTable();
tblBusUnit.Columns.Add("VALUE", typeof(int));
DataRow dRow = tblBusUnit.NewRow();
dRow["Value"] = 1;
tblBusUnit.Rows.Add(dRow);
dRow = tblBusUnit.NewRow();
dRow["Value"] = 6;
tblBusUnit.Rows.Add(dRow);
using (SqlConnection con = new SqlConnection(conACME))
{
con.Open();
SqlDataReader rdr;
SqlCommand cmd = new SqlCommand(
"select bus_unit_id, BusUnit " +
"from BusUnit b " +
"join @tvpBusUnit s on s.value = b.BUS_UNIT_ID;",
con);
cmd.Parameters.Add(
new SqlParameter()
{
ParameterName = "@tvpBusUnit",
SqlDbType = SqlDbType.Structured,
TypeName = "dbo.[DLTableTypeInt]",
Value = tblBusUnit
});
rdr = cmd.ExecuteReader();
while (rdr.Read())
{
string stBusUnitId = rdr["bus_unit_id"].ToString();
string strBusUnit = rdr["BusUnit"].ToString();
Console.WriteLine("Bus Unit:" + strBusUnit);
}
}
return true;
}
How do I do this in NHibernate? I tried the accepted solution of this question by using the Sql2008Structured
and Structured2008Extensions
classes.
See code below that calls the SetStructured()
:
public void SQLSelectTVP<T>()
{
objNSession = NHibernateHelper.GetCurrentSession(strConn);
DataTable tblBusUnit = new DataTable();
tblBusUnit.Columns.Add("VALUE", typeof(int));
DataRow dRow = tblBusUnit.NewRow();
dRow["Value"] = 1;
tblBusUnit.Rows.Add(dRow);
dRow = tblBusUnit.NewRow();
dRow["Value"] = 6;
tblBusUnit.Rows.Add(dRow);
StringBuilder sbSQL = new StringBuilder();
sbSQL.Length = 0;
sbSQL.Append("select bus_unit_id, Business_Unit " +
"from tblBUSINESS_UNIT b " +
"join @tvpBusUnit s on s.value = b.BUS_UNIT_ID");
IQuery sqlQuery = objNSession.CreateSQLQuery(sbSQL.ToString());
sqlQuery.SetStructured("tvpBusUnit", tblBusUnit);
var lstQR = sqlQuery.List<T>();
}
However, it errors because there is no :param
in the SQL:
Parameter tvpBusUnit does not exist as a named parameter in [select bus_unit_id, Business_Unit from tblBUSINESS_UNIT b join @tvpBusUnit s on s.value = b.BUS_UNIT_ID]
How can I fix this?
Upvotes: 2
Views: 2553
Reputation: 105
From the link you posted, I think the way you are accessing the structured variable is incorrect.
s.CreateSQLQuery("EXEC some_sp @id = :id, @par1 = :par1")
.SetStructured("id", dt)
Your code does not use the :id
part, that is, :tvpBusUnit
.
Also note that the TableType
(in TypeName
) may have to be created on the DB beforehand. Please check if this is required. From your code:
TypeName = "dbo.[DLTableTypeInt]",
Some discussion on passing table value parameters is provided here but NHibernate has an update without having to create types like this:
Passing table valued parameters to NHibernate. But this may need a pull-request. The answer provided in the other post you referred to allows you to create such types, one for each TableType
.
Upvotes: 1