2016-03-11 74 views
2

我想爲我的Azure數據庫服務器創建新的數據庫登錄名。它使用SQL管理工作室時,但不是從C#代碼工作,我無法弄清楚是什麼問題。從代碼中創建Azure數據庫登錄引發SqlException

Azure的文檔Manage Database Logins展示瞭如何做到這一點:

-- first, connect to the master database 
CREATE LOGIN login1 WITH password='<ProvidePassword>'; 
CREATE USER login1User FROM LOGIN login1; 
EXEC sp_addrolemember 'dbmanager', 'login1User'; 
EXEC sp_addrolemember 'loginmanager', 'login1User'; 

再次 - 只要我使用SQL Management Studio中這就像一個風情萬種。現在我想從代碼做同樣的事情。請看看我的代碼:

// This is ConnectionString to master database. 
// 'User ID' in this string is sa login created in Azure Portal. 
var cs = "Server=tcp:XXX.database.windows.net,1433;Database=master;User [email protected];Password=XXX;Encrypt=True;TrustServerCertificate=False;Connection Timeout=240"; 

// SQL command 
var command = "CREATE LOGIN testLogin WITH password = 'Test123!!!'"; 

// Execute command using cs 
using (var context = new MyDataContext(cs)) 
{ 
    // works fine - I am connected to the master db 
    context.Database.Connection.Open(); 

    // this line throws exception 
    // "CREATE TABLE permission denied in database 'master'" 
    context.Database.ExecuteSqlCommand(command); 
} 

正如你可以看到我已經嘗試過1:1像文檔說的,但它不起作用。在SQL Management Studio中執行完全相同的操作只是起作用。我也嘗試過很好的SqlConnection以確保它不是由Entity Framework引起的,但不會改變任何內容。

我不知道這裏有什麼區別。我錯過了什麼嗎?任何提示?

EDIT1: 這裏是例外。

消息:

CREATE TABLE permission denied in database 'master'. 

來源:

.Net SqlClient Data Provider 

StrackTrace:

at System.Data.SqlClient.SqlConnection.OnError(SqlException exception, Boolean breakConnection, Action`1 wrapCloseInAction) 
at System.Data.SqlClient.SqlInternalConnection.OnError(SqlException exception, Boolean breakConnection, Action`1 wrapCloseInAction) 
at System.Data.SqlClient.TdsParser.ThrowExceptionAndWarning(TdsParserStateObject stateObj, Boolean callerHasConnectionLock, Boolean asyncClose) 
at System.Data.SqlClient.TdsParser.TryRun(RunBehavior runBehavior, SqlCommand cmdHandler, SqlDataReader dataStream, BulkCopySimpleResultSet bulkCopyHandler, TdsParserStateObject stateObj, Boolean& dataReady) 
at System.Data.SqlClient.SqlCommand.RunExecuteNonQueryTds(String methodName, Boolean async, Int32 timeout, Boolean asyncWrite) 
at System.Data.SqlClient.SqlCommand.InternalExecuteNonQuery(TaskCompletionSource`1 completion, String methodName, Boolean sendToPipe, Int32 timeout, Boolean asyncWrite) 
at System.Data.SqlClient.SqlCommand.ExecuteNonQuery() 
at System.Data.Entity.Infrastructure.Interception.DbCommandDispatcher.<NonQuery>b__0(DbCommand t, DbCommandInterceptionContext`1 c) 
at System.Data.Entity.Infrastructure.Interception.InternalDispatcher`1.Dispatch[TTarget,TInterceptionContext,TResult](TTarget target, Func`3 operation, TInterceptionContext interceptionContext, Action`3 executing, Action`3 executed) 
at System.Data.Entity.Infrastructure.Interception.DbCommandDispatcher.NonQuery(DbCommand command, DbCommandInterceptionContext interceptionContext) 
at System.Data.Entity.Internal.InterceptableDbCommand.ExecuteNonQuery() 
at System.Data.Entity.Migrations.DbMigrator.ExecuteSql(MigrationStatement migrationStatement, DbConnection connection, DbTransaction transaction, DbInterceptionContext interceptionContext) 
at System.Data.Entity.Migrations.DbMigrator.ExecuteStatementsInternal(IEnumerable`1 migrationStatements, DbConnection connection, DbTransaction transaction, DbInterceptionContext interceptionContext) 
at System.Data.Entity.Migrations.DbMigrator.ExecuteStatementsWithinTransaction(IEnumerable`1 migrationStatements, DbTransaction transaction, DbInterceptionContext interceptionContext) 
at System.Data.Entity.Migrations.DbMigrator.ExecuteStatementsWithinNewTransaction(IEnumerable`1 migrationStatements, DbConnection connection, DbInterceptionContext interceptionContext) 
at System.Data.Entity.Migrations.DbMigrator.ExecuteStatementsInternal(IEnumerable`1 migrationStatements, DbConnection connection, DbInterceptionContext interceptionContext) 
at System.Data.Entity.Migrations.DbMigrator.ExecuteStatementsInternal(IEnumerable`1 migrationStatements, DbConnection connection) 
at System.Data.Entity.Migrations.DbMigrator.<>c__DisplayClass30.<ExecuteStatements>b__2e() 
at System.Data.Entity.SqlServer.DefaultSqlExecutionStrategy.<>c__DisplayClass1.<Execute>b__0() 
at System.Data.Entity.SqlServer.DefaultSqlExecutionStrategy.Execute[TResult](Func`1 operation) 
at System.Data.Entity.SqlServer.DefaultSqlExecutionStrategy.Execute(Action operation) 
at System.Data.Entity.Migrations.DbMigrator.ExecuteStatements(IEnumerable`1 migrationStatements, DbTransaction existingTransaction) 
at System.Data.Entity.Migrations.DbMigrator.ExecuteStatements(IEnumerable`1 migrationStatements) 
at System.Data.Entity.Migrations.DbMigrator.ExecuteOperations(String migrationId, VersionedModel targetModel, IEnumerable`1 operations, IEnumerable`1 systemOperations, Boolean downgrading, Boolean auto) 
at System.Data.Entity.Migrations.DbMigrator.ApplyMigration(DbMigration migration, DbMigration lastMigration) 
at System.Data.Entity.Migrations.DbMigrator.Upgrade(IEnumerable`1 pendingMigrations, String targetMigrationId, String lastMigrationId) 
at System.Data.Entity.Migrations.DbMigrator.UpdateInternal(String targetMigration) 
at System.Data.Entity.Migrations.DbMigrator.<>c__DisplayClassc.<Update>b__b() 
at System.Data.Entity.Migrations.DbMigrator.EnsureDatabaseExists(Action mustSucceedToKeepDatabase) 
at System.Data.Entity.Migrations.DbMigrator.Update(String targetMigration) 
at System.Data.Entity.Internal.DatabaseCreator.CreateDatabase(InternalContext internalContext, Func`3 createMigrator, ObjectContext objectContext) 
at System.Data.Entity.Internal.InternalContext.CreateDatabase(ObjectContext objectContext, DatabaseExistenceState existenceState) 
at System.Data.Entity.Database.Create(DatabaseExistenceState existenceState) 
at System.Data.Entity.CreateDatabaseIfNotExists`1.InitializeDatabase(TContext context) 
at System.Data.Entity.Internal.InternalContext.<>c__DisplayClassf`1.<CreateInitializationAction>b__e() 
at System.Data.Entity.Internal.InternalContext.PerformInitializationAction(Action action) 
at System.Data.Entity.Internal.InternalContext.PerformDatabaseInitialization() 
at System.Data.Entity.Internal.LazyInternalContext.<InitializeDatabase>b__4(InternalContext c) 
at System.Data.Entity.Internal.RetryAction`1.PerformAction(TInput input) 
at System.Data.Entity.Internal.LazyInternalContext.InitializeDatabaseAction(Action`1 action) 
at System.Data.Entity.Internal.LazyInternalContext.InitializeDatabase() 
at System.Data.Entity.Internal.InternalContext.ExecuteSqlCommand(TransactionalBehavior transactionalBehavior, String sql, Object[] parameters) 
at System.Data.Entity.Database.ExecuteSqlCommand(TransactionalBehavior transactionalBehavior, String sql, Object[] parameters) 
at System.Data.Entity.Database.ExecuteSqlCommand(String sql, Object[] parameters) 
+1

請問您可以添加例外嗎? – Jay

+0

MSDN上的這篇文章可能有所幫助:https://msdn.microsoft.com/en-us/library/ms173463.aspx。這可能是因爲你使用的連接字符串只允許你訪問特定的數據庫(登錄是在SQL實例上創建的,它包含許多數據庫,包括「master」)。你可能需要一個複合語句,比如'CREATE LOGIN AbolrousHazem WITH PASSWORD ='340 $ Uuxwp7Mcxo7Khy'; USE AdventureWorks2008R2; CREATE USER AbolrousHazem FOR LOGIN AbolrousHazem; GO' – NickT

+0

從C#代碼拋出的異常是否存在任何內部異常? – juvchan

回答

0

根據您的堆棧跟蹤,它看起來像實體框架試圖運行之前運行的遷移, SQL命令。由於您的連接字符串指向主數據庫(而不是您的用戶數據庫),因此遷移嘗試在主服務器中創建不允許您執行的表。

如果您確實需要從您的應用程序代碼創建新的SQL登錄名,一種解決方案是將您的主Entity Framework連接字符串指向您的用戶數據庫,並使用master數據庫的連接字符串創建單獨的SqlConnection創建登錄步驟。