SqlDbType.Structured для передачи табличных значений в NHibernate для выбора без параметра: param?
Я хочу передать набор идентификаторов (через параметр table-valued) в оператор NHibernate IQuery
select
, который будет использоваться в соединении:
В родном SQL я могу это сделать (SQLSelectData ниже). Обратите внимание, что в SqlCommand
sql:22 > нет :param
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;
}
Как это сделать в NHibernate? Я пробовал принятое решение этого вопроса с помощью Sql2008Structured
и Structured2008Extensions
классы.
Смотрите код ниже, который вызывает 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>();
}
Однако, это ошибки, потому что в SQL не существует :param
:
Параметр tvpBusUnit не существует как именованный параметр в [select bus_unit_id, Business_Unit from tblBUSINESS_UNIT b join @tvpBusUnit s on s.value = b.BUS_UNIT_ID]
Как я могу это исправить?
Ответы
Ответ 1
Из опубликованной вами ссылки, я думаю, что способ доступа к структурированной переменной неверен.
s.CreateSQLQuery("EXEC some_sp @id = :id, @par1 = :par1")
.SetStructured("id", dt)
В вашем коде не используется часть :id
, то есть :tvpBusUnit
.
Также обратите внимание, что TableType
(in TypeName
), возможно, необходимо создать на БД заранее. Проверьте, требуется ли это. Из вашего кода:
TypeName = "dbo.[DLTableTypeInt]",
Здесь приводится некоторое обсуждение параметров параметров передачи таблицы, но у NHibernate есть обновление без необходимости создания таких типов:
Передача табличных параметров в NHibernate. Но для этого может потребоваться запрос на pull. Ответ, указанный в другом сообщении, который вы указали, позволяет создавать такие типы, по одному для каждого TableType
.