2016-03-11 75 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创建登录步骤。