无法立即连接到新创建的SQL Server数据库

我正在使用SQL Server管理对象创建数据库。

我编写了以下方法来生成数据库:

public static void CreateClientDatabase(string serverName, string databaseName) { using (var connection = new SqlConnection(GetClientSqlConnectionString(serverName, String.Empty))) { var server = new Server(new ServerConnection(connection)); var clientDatabase = new Database(server, databaseName); clientDatabase.Create(); server.ConnectionContext.Disconnect(); } } 

此后不久,我调用另一种方法来执行SQL脚本来生成表格等:

 public static void CreateClientDatabaseObjects(string createDatabaseObjectsScriptPath, string serverName, string databaseName) { using (var connection = new SqlConnection(GetClientSqlConnectionString(serverName, databaseName))) { string createDatabaseObjectsScript = new FileInfo(createDatabaseObjectsScriptPath).OpenText().ReadToEnd(); var server = new Server(new ServerConnection(connection)); server.ConnectionContext.ExecuteNonQuery(createDatabaseObjectsScript); server.ConnectionContext.Disconnect(); } } 

语句server.ConnectionContext.ExecuteNonQuery(createDatabaseObjectsScript)抛出SqlException ,并显示消息无法打开登录请求的数据库“数据库名称”。 登录失败。 用户’用户’登录失败。

如果我尝试单步执行调试器中的语句,则不会发生此exception并且脚本执行正常。

我唯一的猜测是服务器需要一些时间来初始化数据库才能打开它。 这准确吗? 有没有办法告诉数据库是否准备就绪,而不是尝试连接失败?

编辑:我应该提到数据库肯定是在所有情况下创建的。

编辑2:在创建数据库之前,我调用EntityFramework.dll的System.Data.Entity.Database.Exists方法来检查数据库是否已存在。 如果我删除该调用,一切似乎都按预期工作。 这几乎就好像该调用缓存结果并弄乱后续连接看到新数据库(无论它们是否使用entity framework)。

编辑3:我使用Server.Databases.Contains(databaseName)替换了EntityFramework的Database.Exists方法和基于SMO的方法。 我得到了同样的问题,因为创建后无法立即打开数据库。 同样,如果我在创建之前没有检查数据库是否存在,我可以在创建它之后立即打开它,但我希望能够在创建之前检查存在,所以我不会尝试创建现有数据库。

EntityFramework的Database.Exists和SMO的Server.Databases.Contains执行在master.sys.databases中查找数据库名称的SQL。 我不明白为什么/如何干扰数据库连接。

刚上线的数据库不一定准备好接受连接。 要确定数据库何时可以接受连接,请查询sys.databases的collat​​ion_name列或DATABASEPROPERTYEX的Collat​​ion属性。 当数据库排序规则返回非空值时,数据库可以接受连接。

数据库名称“登录请求。登录失败。登录失败,用户’用户’

这里要注意的一件事是错误信息是围绕安全性的。 您是如何尝试登录新数据库的(即用于新数据库连接的连接字符串是什么类型的安全性)? 如果您使用的是SQL身份validation,则需要发出sp_adduser以授予对数据库的登录访问权限。

http://msdn.microsoft.com/en-us/library/ms181422.aspx

在我的例子中,事实certificate问题不是新创建的数据库没有准备好。 但问题是SqlConnection.Open()显然使用了失败的缓存连接,然后再次返回相同的错误。

在我尝试打开新创建的数据库之前调用静态SqlConnection.ClearAllPools()方法时,它工作正常!

另见这个问题。

您必须接近数据库创建有点不同。 下面的代码正确处理数据库创建。 试试吧 ;)

 private void CreateDatabase(string databaseName)
 {

     Microsoft.SqlServer.Management.Smo.Server sqlServer = 
            新的Microsoft.SqlServer.Management.Smo.Server(_connection);

    数据库createdDatabase = new Database();
     createdDatabase.Name = databaseName;
     createdDatabase.Parent = sqlServer;
     createdDatabase.Create();

 }

在下面的代码中,_connection是一个

  Microsoft.SqlServer.Management.Smo.ServerConnection 

顺便提一下对象。

[编辑]修改代码,以便不再吞下exception。