问题
My code looks like this:
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();
}
}
}
The code works fine but if I do not commit the transaction it throws an exception as shown
System.InvalidOperationException: ExecuteNonQuery requires the command to have a transaction when the connection assigned to the command is in a pending local transaction. The Transaction property of the command has not been initialized.
But I don't want the transaction to be commited yet before completing the whole operation. How can I achieve this??
回答1:
the issue is that the transaction was supposed to use has been committed and already has been disposed, thus either instantiate a new SqlConnection or get a new session and then run the query as part of the new session.
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();
}
}
}
or
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();
}
}
}
BTW, why are using SQLConnection why arent you exexurting the query using the Nhibernate Session, you could do the everything that you are doing right now using the Nhibernate Session.
session.CreateSQLQuery(<your sql>)
.SetParameters() //and various other API to set your parameters
.ExecuteUpdate();
来源:https://stackoverflow.com/questions/10292695/how-to-pass-datatable-as-a-parameter-to-stored-procedure-by-not-commiting-the-cu