在NHibernate中使用来自ISession的连接

时间:2016-12-01 20:53:00

标签: c# sql-server nhibernate

我正在学习nHibernate和特定会话,因为我遇到了nHibernate不支持SetParameter()方法中的表值参数的问题。遗憾的是,这是一个问题,因为我有一个存储过程,旨在获取一个表值参数。搜索堆栈溢出时,我遇到了一些涉及此问题的其他问题,这些问题详细说明了使用来自ISession的连接来使用ADO.NET执行操作。 (以下链接)

How to pass DataTable as a parameter to Stored Procedure by not commiting the current session transaction?

使用这个我把以下代码放在一起。该方法采用Guids列表,并且应该返回设备GUID的过滤列表。

          var myTable = new DataTable("dbo.EntityIds");
          var dataset = new DataSet();
          myTable.Columns.Add("deviceId", typeof (Guid));
          foreach (Guid deviceId in deviceIds)
          {
              myTable.Rows.Add(deviceId);
          }

          var con = Session.SessionFactory.OpenSession().GetSessionImplementation().Connection;
          using (var sqlConnection = (SqlConnection) con)
          {
              using (var cmd = sqlConnection.CreateCommand())
              {
                  cmd.CommandType = CommandType.StoredProcedure;
                  cmd.CommandText = "dbo.GetLastCommunicationStatus";
                  cmd.Parameters.Add("@DeviceTableVar", SqlDbType.Structured);
                  var sqlParam = cmd.Parameters["@DeviceTableVar"];
                  sqlParam.Direction = ParameterDirection.Input;
                  sqlParam.TypeName = "[dbo].[EntityIds]";
                  sqlParam.Value = myTable;
                  var adapt = new SqlDataAdapter();
                  adapt.SelectCommand = cmd;
                  adapt.Fill(dataset);
              }
          }

          deviceFailureList =
              dataset.Tables[0].AsEnumerable().Select(dataRow => dataRow.Field<Guid>("deviceId")).ToList();

我在这种情况下最终要问的问题是刚刚开放的Session会发生什么?

另外,有没有办法传递我可能错过的表值参数?我知道由于SetParameters()方法不支持tabled参数,以下内容不起作用:

session.CreateSQLQuery(...)
.SetParameters(...)   //and various other API to set your parameters
.ExecuteUpdate();

我还没有尝试过的唯一一件事就是......

using(ITransaction transaction = session.BeginTransaction())
{
        …NHibernate stuff…

        IDbCommand command = new SqlCommand();
        command.Connection = session.Connection;
        transaction.Enlist(command);
        command.CommandText = “delete from User where clue is null”;
        command.ExecuteNonQuery();

        …more NHibernate stuff… 
}

最终的代码段来自此博客条目:

enlisting ADO commands in NHibernate

是否可以让事务对象登记SqlCommand而不是IDbCommand?我问的原因是,在我的第一个代码片段中,我正在分配一个DataTable参数,并且看起来我不能使用IDbCommand这样做。

更新:

所以我设法让代码使用ITransaction对象的Enlist()方法。下面给出的例子......

          using (ITransaction trans = Session.BeginTransaction())
          {                     
              SqlCommand unboxed = new SqlCommand();
              unboxed.CommandType = CommandType.StoredProcedure;
              unboxed.Connection = (SqlConnection)Session.Connection;
              unboxed.CommandText = "dbo.GetLastCommunicationStatus";
              unboxed.Parameters.Add("@DeviceTableVar", SqlDbType.Structured);
              var sqlParam = unboxed.Parameters["@DeviceTableVar"];
              sqlParam.Direction = ParameterDirection.Input;
              sqlParam.TypeName = "[dbo].[EntityIds]";
              sqlParam.Value = myTable;
              IDbCommand cmd = unboxed;
              trans.Enlist(cmd);
              var adapt = new SqlDataAdapter();
              adapt.SelectCommand = (SqlCommand)cmd;
              adapt.Fill(dataset);
          }

我之前的不确定性主要是将SqlCommand的拆箱和装箱作为IDbCommand。但是,上述确实似乎有效。

0 个答案:

没有答案