How can I get NHibernate to make a multicolumn table-valued parameter?

徘徊边缘 提交于 2019-12-23 05:27:50

问题


I'd like to pass a two-column table-valued parameter (TVP) to an 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();

When I do this (or try to hint the IType as NHibernateUtil.Object or NHibernateUtil.Class), NHibernate complains:

NHibernate.HibernateException : Could not determine a type for class: <>f__AnonymousType5`2[[System.Int32],[System.String]]

It also complains if I try to make a struct with properties for movieID and score and make an array of those instead of anonymous objects. The only thing that changes is the type it "could not determine."

Microsoft seems to say that a TVP can have whatever columns you want:

Passing a Table-Valued Parameter to a Parameterized SQL Statement

The following example demonstrates how to insert data into the dbo.Categories table by using an INSERT statement with a SELECT subquery that has a table-valued parameter as the data source. When passing a table-valued parameter to a parameterized SQL statement, you must specify a type name for the table-valued parameter by using the new TypeName property of a SqlParameter. This TypeName must match the name of a compatible type previously created on the server. The code in this example uses the TypeName property to reference the type structure defined in 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();  
}

Is there a way to convince NHibernate to make a TVP with named columns? I'd like to avoid writing my own IType.


回答1:


Remondo has a novel solution to this problem: Add the TVP definition to the transaction with a SqlParameter from the Microsoft library.

Edit to follow with sample code for the query in the question.



来源:https://stackoverflow.com/questions/46244598/how-can-i-get-nhibernate-to-make-a-multicolumn-table-valued-parameter

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!