我正在使用 SQL Server Management Objects 创建数据库.
我写了下面的方法生成数据库:
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
消息 无法打开登录请求的数据库“数据库名称”。登录失败。
用户“用户”登录失败。
如果我尝试单步执行调试器中的语句,此异常从不 发生并且脚本执行正常。
我唯一的猜测是服务器需要一些时间来初始化数据库,然后才能打开它。这是准确的吗?除了尝试连接和连接失败之外,是否有其他方法可以判断数据库是否准备就绪?
编辑:我应该提一下,在所有情况下肯定都在创建数据库。
编辑 2:在创建数据库之前,我调用了 System.Data.Entity.Database.Exists EntityFramework.dll 的方法来检查数据库是否已经存在。如果我删除那个电话,一切似乎都按预期工作。几乎就好像该调用正在缓存结果并使后续连接无法看到新数据库(无论它们是否使用 Entity Framework)。
编辑 3:我使用 Server.Databases.Contains(databaseName)
将 EntityFramework 的 Database.Exists
方法替换为基于 SMO 的方法.我遇到同样的问题,因为创建后无法立即打开数据库。同样,如果我在创建之前不检查数据库是否存在,我可以在创建后立即打开它,但我希望能够在创建之前检查是否存在,所以我不会尝试创建现有数据库。
EntityFramework 的 Database.Exists
和 SMO 的 Server.Databases.Contains
都只是执行在 master.sys.databases 中查找数据库名称的 SQL。我不明白为什么/如何干扰数据库连接。
最佳答案
刚上线的数据库不一定准备好接受连接。要确定数据库何时可以接受连接,请查询 sys.databases 的 collation_name 列或 DATABASEPROPERTYEX 的 Collation 属性。当数据库排序规则返回非空值时,数据库可以接受连接。
关于c# - 无法立即连接到新创建的 SQL Server 数据库,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9297098/