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.