问题
Following examples 1, 2 I wrote the following:
using System;
using System.Data.SqlClient;
using System.IO;
using Microsoft.SqlServer.Management.Smo;
using Microsoft.SqlServer.Management.Common;
namespace ScriptRunner
{
class Program
{
static void Main(string[] args)
{
var script = File.ReadAllText("Test.sql");
const string sqlConnectionString = @"Data Source=my\ds;
Initial Catalog=myic;
Connection Timeout=0;
Integrated Security=true";
SqlConnection connection = null;
Server server = null;
try
{
connection = new SqlConnection(sqlConnectionString);
server = new Server(new ServerConnection(connection));
connection.Open();
server.ConnectionContext.BeginTransaction();
server.ConnectionContext.ExecuteNonQuery(script);
server.ConnectionContext.CommitTransaction();
}
catch { server.ConnectionContext.RollBackTransaction(); }
finally { connection?.Dispose(); }
}
}
}
Everything works, except the transactions. The command just runs, if there is the error, everything before is already in database. How to make transactions work here?
[EDIT] When I change the code to open the transaction at the SqlConnection level like this (here it's suggested, that there should be no difference):
SqlTransaction transaction = null;
try
{
connection = new SqlConnection(sqlConnectionString);
server = new Server(new ServerConnection(connection));
connection.Open();
transaction = connection.BeginTransaction();
server.ConnectionContext.ExecuteNonQuery(script);
transaction.Commit();
}
It throws InvalidOPexception : "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."
Yet I do not see a place where I can access the command object.
回答1:
I've faced with same problem "ExecuteNonQuery requires the command to have a transaction...".
It seems that if perform begin/commit transaction for ServerConnection, not for SqlConnection then everything works.
...
SqlConnection connection = new SqlConnection(sqlConnectionString);
ServerConnection srvCon = new ServerConnection(connection);
try
{
server = new Server(srvCon);
srvCon.BeginTransaction();
server.ConnectionContext.ExecuteNonQuery(script);
srvCon.CommitTransaction();
}
catch
{
srvCon.RollBackTransaction();
}
...
来源:https://stackoverflow.com/questions/47204709/how-to-use-transactions-in-smo-server-connectioncontext