0

Мой код выглядит следующим образом:Как передать DataTable в качестве параметра хранимой процедуры, не совершая транзакции текущего сеанса?

public void InsertSampleData(DataTable tempTable) 
    { 
     session.Transaction.Commit(); 
     var connection = session.GetSessionImplementation().Connection; 
     using (var sqlConnection = (SqlConnection)connection) 
     { 
      using (var cmd = sqlConnection.CreateCommand()) 
      { 
       cmd.CommandType = CommandType.StoredProcedure; 
       cmd.CommandText = "dbo.insertData"; 
       cmd.Parameters.Add("@sItems", SqlDbType.Structured); 
       var sqlParam = cmd.Parameters["@Items"]; 
       sqlParam.Direction = ParameterDirection.Input; 
       sqlParam.TypeName = "[dbo].[DataItemType]"; 
       sqlParam.Value = tempTable; 
       cmd.ExecuteNonQuery(); 
      } 
     } 
    } 

код работает нормально, но если я не совершить сделку он бросает исключение, как показано

System.InvalidOperationException: ExecuteNonQuery требует команды, чтобы иметь когда соединение, назначенное команде , находится в ожидающей локальной транзакции. Свойство Transaction команды не было инициализировано.

Но я не хочу, чтобы транзакция была совершена еще до завершения всей операции. Как я могу это достичь?

+0

Что возвращает GetSessionImplementation? – Baz1nga

+0

@ Baz1nga его возвращает что-то, что реализует [ISession] (http://mausch.github.com/nhibernate-3.2.0GA/html/fcb2b8a0-0c03-8056-91a1-3b26691eaffe.htm) его вещь nhibernate –

+0

NHibernate.Engine .ISessionImplementor GetSessionImplementation() Член NHibernate.ISession Основная информация: Получает выполнение сеанса. Возвращает: NHibernate реализация интерфейса NHibernate.Engine.ISessionImplementor Примечания: Этот метод предоставляется для того, чтобы получить реализацию NHibernate сессии из оберток implementions. Разработчики интерфейса NHibernate.ISession должны вернуть реализацию этого метода NHibernate. –

ответ

1

проблема заключается в том, что транзакция должна была быть использована и была уже удалена, поэтому либо создайте новый SqlConnection, либо получите новый сеанс, а затем запустите запрос как часть нового сеанса.

public void InsertSampleData(DataTable tempTable) 
{ 
    session.Transaction.Commit(); 

    using (var sqlConnection = new SqlConnection(session.GetSessionImplementation() 
             .Connection.ConnectionString)) 
    { 
     using (var cmd = sqlConnection.CreateCommand()) 
     { 
      cmd.CommandType = CommandType.StoredProcedure; 
      cmd.CommandText = "dbo.insertData"; 
      cmd.Parameters.Add("@sItems", SqlDbType.Structured); 
      var sqlParam = cmd.Parameters["@Items"]; 
      sqlParam.Direction = ParameterDirection.Input; 
      sqlParam.TypeName = "[dbo].[DataItemType]"; 
      sqlParam.Value = tempTable; 
      cmd.ExecuteNonQuery(); 
     } 
    } 
} 

или

public void InsertSampleData(DataTable tempTable) 
    { 
     session.Transaction.Commit(); 
     var connection = session.SessionFactory.OpenSession().GetSessionImplementation().Connection; 
     using (var sqlConnection = (SqlConnection)connection) 
     { 
      using (var cmd = sqlConnection.CreateCommand()) 
      { 
       cmd.CommandType = CommandType.StoredProcedure; 
       cmd.CommandText = "dbo.insertData"; 
       cmd.Parameters.Add("@sItems", SqlDbType.Structured); 
       var sqlParam = cmd.Parameters["@Items"]; 
       sqlParam.Direction = ParameterDirection.Input; 
       sqlParam.TypeName = "[dbo].[DataItemType]"; 
       sqlParam.Value = tempTable; 
       cmd.ExecuteNonQuery(); 
      } 
     } 
    } 

Кстати, почему используют SQLConnection почему ARENT вы exexurting запрос с помощью NHibernate сессии, вы могли бы сделать все, что вы делаете прямо сейчас, используя NHibernate сессии.

session.CreateSQLQuery(<your sql>) 
.SetParameters() //and various other API to set your parameters 
.ExecuteUpdate(); 
+0

Да, я пробовал использовать сеанс Nhibernate, но как вы передаете параметр DataTable как параметр, потому что хранимая процедура ожидает параметр, зависящий от таблицы –

Смежные вопросы