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

GWB*_*GWB 9 .net c# sql-server smo

我正在使用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();
    }
}
Run Code Online (Sandbox Code Playgroud)

此后不久,我调用另一种方法来执行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();
    }
}
Run Code Online (Sandbox Code Playgroud)

该语句server.ConnectionContext.ExecuteNonQuery(createDatabaseObjectsScript)抛出一条SqlException消息无法打开登录请求的数据库"数据库名称".登录失败.用户'用户'登录失败.

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

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

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

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

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

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

Dav*_*ant 8

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


Rob*_*ner 5

就我而言,事实证明问题不在于新创建的数据库尚未准备好。但问题是,SqlConnection.Open()显然使用了失败的缓存连接,然后又返回了相同的错误。

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

另请参阅这个问题。