Il se trouve qu'il y avait plusieurs problèmes avec le code que j'avais. SMO est encore assez loufoque quand il s'agit de SQL Azure. Donc, poster mes conclusions au cas où quelqu'un traverserait la même route caillouteuse.
- SMO commute la base de données par défaut dans les coulisses chaque fois que vous obtenez un objet de base de données comme ceci:
Database database = server.Databases[databaseName]
catalogue initial devient maître et vous pouvez le voir dans la chaîne de connexion qui change dans server.ConnectionContext.ConnectionString (SQL "normal" ne le fait pas). La résolution pour cela était d'ouvrir une nouvelle connexion (et de fermer l'ancienne) chaque fois que la base de données est passée à Master, puisque le nom de la base de données ne peut pas être changé une fois la connexion établie (apparemment, seul SQL Azure peut le faire). L'ouverture d'une connexion, avec laquelle ServerConnection et Server sont initialisés, échouera parfois en conjonction avec le premier problème.
- Cela donnerait un message d'erreur obscur indiquant que la connexion a échoué donnant un guid et un horodatage demandant de contacter le support client. Absurdité. La résolution de ce problème était de ne pas ouvrir la connexion et laissez ServerConnection l'ouvrir lors de l'initialisation de l'objet serveur:
- Enfin, Alter() n'est pas aimé par Azure SQL sur l'objet Server. Retiré tous les Alter.
Donc, l'extrait de code final ressemble à quelque chose comme ceci:
string connectionString = "Server=tcp:XXXXX.database.windows.net;Database=XXXXXX;User ID=XXXXXX;Password=XXXXX;Trusted_Connection=False;Encrypt=True;trustservercertificate=true";
SqlConnection connection = new SqlConnection(connectionString);
// do not explicitly open connection, it will be opened when Server is initialized
// connection.Open();
ServerConnection serverConnection = new ServerConnection(connection);
Server server = new Server(serverConnection);
// after this line, the default database will be switched to Master
Database database = server.Databases["MyDatabase"];
// you can still use this database object and server connection to
// do certain things against this database, like adding database roles
// and users
DatabaseRole role = new DatabaseRole(database, "NewRole");
role.Create();
// if you want to execute a script against this database, you have to open
// another connection and re-initiliaze the server object
server.ConnectionContext.Disconnect();
connection = new SqlConnection(connectionString);
serverConnection = new ServerConnection(connection);
server = new Server(serverConnection);
server.ConnectionContext.ExecuteNonQuery("CREATE TABLE New (NewId int)");
Et voici l'exception obscure pour le point # 2 cas où quelqu'un est intéressé:
Microsoft.SqlServer.Management.Common.ConnectionFailureException was unhandled
Message=Failed to connect to server .
Source=Microsoft.SqlServer.Smo
StackTrace:
at Microsoft.SqlServer.Management.Smo.DatabaseCollection.get_Item(String name)
InnerException: System.Data.SqlClient.SqlException
Message=Login failed for user 'XXXXXXXX'.
This session has been assigned a tracing ID of 'XXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXX'. Provide this tracing ID to customer support when you need assistance.
Source=.Net SqlClient Data Provider
ErrorCode=-2146232060
Class=14
LineNumber=65536
Number=18456
Procedure=""
Server=tcp:XXXXXXXX.database.windows.net
State=1
StackTrace:
at System.Data.SqlClient.SqlInternalConnection.OnError(SqlException exception, Boolean breakConnection)
at System.Data.SqlClient.TdsParser.ThrowExceptionAndWarning()
at System.Data.SqlClient.TdsParser.Run(RunBehavior runBehavior, SqlCommand cmdHandler, SqlDataReader dataStream, BulkCopySimpleResultSet bulkCopyHandler, TdsParserStateObject stateObj)
at System.Data.SqlClient.SqlInternalConnectionTds.CompleteLogin(Boolean enlistOK)
at System.Data.SqlClient.SqlInternalConnectionTds.AttemptOneLogin(ServerInfo serverInfo, String newPassword, Boolean ignoreSniOpenTimeout, TimeoutTimer timeout, SqlConnection owningObject)
at System.Data.SqlClient.SqlInternalConnectionTds.LoginNoFailover(ServerInfo serverInfo, String newPassword, Boolean redirectedUserInstance, SqlConnection owningObject, SqlConnectionString connectionOptions, TimeoutTimer timeout)
at System.Data.SqlClient.SqlInternalConnectionTds.OpenLoginEnlist(SqlConnection owningObject, TimeoutTimer timeout, SqlConnectionString connectionOptions, String newPassword, Boolean redirectedUserInstance)
at System.Data.SqlClient.SqlInternalConnectionTds..ctor(DbConnectionPoolIdentity identity, SqlConnectionString connectionOptions, Object providerInfo, String newPassword, SqlConnection owningObject, Boolean redirectedUserInstance)
at System.Data.SqlClient.SqlConnectionFactory.CreateConnection(DbConnectionOptions options, Object poolGroupProviderInfo, DbConnectionPool pool, DbConnection owningConnection)
at System.Data.ProviderBase.DbConnectionFactory.CreatePooledConnection(DbConnection owningConnection, DbConnectionPool pool, DbConnectionOptions options)
at System.Data.ProviderBase.DbConnectionPool.CreateObject(DbConnection owningObject)
at System.Data.ProviderBase.DbConnectionPool.UserCreateRequest(DbConnection owningObject)
at System.Data.ProviderBase.DbConnectionPool.GetConnection(DbConnection owningObject)
at System.Data.ProviderBase.DbConnectionFactory.GetConnection(DbConnection owningConnection)
at System.Data.ProviderBase.DbConnectionClosed.OpenConnection(DbConnection outerConnection, DbConnectionFactory connectionFactory)
at System.Data.SqlClient.SqlConnection.Open()
at Microsoft.SqlServer.Management.Common.ConnectionManager.InternalConnect(WindowsIdentity impersonatedIdentity)
at Microsoft.SqlServer.Management.Common.ConnectionManager.Connect()
Avez-vous essayé d'utiliser SqlCommand comme indiqué dans cet exemple http://msdn.microsoft.com/en-us/library/ee336243.aspx? –
Je reçois la même erreur avec SqlCommand – kateroh