如何让NHibernate创建一个多列表值参数?

时间:2017-09-15 17:10:14

标签: nhibernate table-valued-parameters

我想将两列表值参数(TVP)传递给ISQLQuery

var sql = "INSERT INTO MovieRatings (PersonID, MovieID, Score) " +
          "SELECT :personID, o.movieID, o.score " +
          "FROM :scoreObject o";
var query = session.CreateSQLQuery(sql);
query.SetInt32("personID", fred.ID);
query.SetParameterList("scoreObject", fredsRatings.Select(r => new {
        movieID = r.Movie.ID,
        score = r.Score
    }).ToArray() /*, Optional IType hint here */);
query.ExecuteUpdate();

当我这样做(或尝试将IType提示为NHibernateUtil.ObjectNHibernateUtil.Class)时,NHibernate会抱怨:

  

NHibernate.HibernateException:无法确定类的类型:<>f__AnonymousType5`2[[System.Int32],[System.String]]

如果我尝试使用structmovieID的属性创建score,并且创建一个数组而不是匿名对象,它也会抱怨。唯一改变的是它“无法确定的类型”。

Microsoft seems to say,TVP可以拥有您想要的任何列:

  

将表值参数传递给参数化SQL语句

     

以下示例演示如何使用dbo.Categories语句将INSERT表插入SELECT表,该子查询具有表值参数作为数据源。将表值参数传递给参数化SQL语句时,必须使用TypeName的新SqlParameter属性为表值参数指定类型名称。此TypeName必须与先前在服务器上创建的兼容类型的名称匹配。此示例中的代码使用TypeName属性来引用dbo.CategoryTableType中定义的类型结构。

// Assumes connection is an open SqlConnection.  
using (connection)  
{  
    // Create a DataTable with the modified rows.  
    DataTable addedCategories = CategoriesDataTable.GetChanges(  
        DataRowState.Added);  

    // Define the INSERT-SELECT statement.  
    string sqlInsert =   
        "INSERT INTO dbo.Categories (CategoryID, CategoryName)"  
        + " SELECT nc.CategoryID, nc.CategoryName"  
        + " FROM @tvpNewCategories AS nc;"  

    // Configure the command and parameter.  
    SqlCommand insertCommand = new SqlCommand(  
        sqlInsert, connection);  
    SqlParameter tvpParam = insertCommand.Parameters.AddWithValue(  
        "@tvpNewCategories", addedCategories);  
    tvpParam.SqlDbType = SqlDbType.Structured;  
    tvpParam.TypeName = "dbo.CategoryTableType";  

    // Execute the command.  
    insertCommand.ExecuteNonQuery();  
}

有没有办法说服NHibernate制作带有命名列的TVP?我想避免writing my own IType.

1 个答案:

答案 0 :(得分:0)

雷蒙多(Remondo)解决了a novel solution:使用Microsoft库中的SqlParameter将TVP定义添加到事务中。

进行编辑以提供问题中查询的示例代码。