我想将两列表值参数(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.Object
或NHibernateUtil.Class
)时,NHibernate会抱怨:
NHibernate.HibernateException
:无法确定类的类型:<>f__AnonymousType5`2[[System.Int32],[System.String]]
如果我尝试使用struct
和movieID
的属性创建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
.
答案 0 :(得分:0)
雷蒙多(Remondo)解决了a novel solution:使用Microsoft库中的SqlParameter
将TVP定义添加到事务中。
进行编辑以提供问题中查询的示例代码。