如何检查 LocalDB 中的数据库创建是否完成
How to check if database creation in LocalDB is finished
我在一个项目中使用 SQL 服务器作为数据库以及 Entity Framework Core 3.1。对于单元测试/集成测试,我们使用 LocalDB。
为确保 LocalDB 数据库处于正确的迁移状态,我们删除并重新创建测试数据库。
看起来像这样:
using (var sqlConnection = new SqlConnection(@"Data Source=(localdb)\MSSQLLocalDB;Integrated Security=True"))
{
sqlConnection.Open();
new SqlCommand("USE MASTER", sqlConnection).ExecuteNonQuery();
try
{
new SqlCommand($"ALTER DATABASE [MyTestDb] SET SINGLE_USER WITH ROLLBACK IMMEDIATE", sqlConnection).ExecuteNonQuery();
new SqlCommand($"DROP DATABASE [MyTestDb]", sqlConnection).ExecuteNonQuery();
}
catch (SqlException e)
{
// We get an error if there is no database. This happens the very first time a test gets executed on a machine
}
new SqlCommand($"CREATE DATABASE [MyTestDb];", sqlConnection).ExecuteNonQuery();
new SqlCommand($"ALTER DATABASE [MyTestDb] SET ALLOW_SNAPSHOT_ISOLATION ON;", sqlConnection).ExecuteNonQuery();
new SqlCommand($"ALTER DATABASE [MyTestDb] SET READ_COMMITTED_SNAPSHOT ON;", sqlConnection).ExecuteNonQuery();
}
using (var creationConnection = new SqlConnection(@$"Data Source=(localdb)\MSSQLLocalDB;Integrated Security=True;Initial Catalog=MyTestDb"))
{
creationConnection.Open(); // <-- Problematic exception here
using (var context = new MyDbContext(/*some DbContextOptions here... */))
{
context.Database.Migrate();
}
}
这将在 creationConnection.Open();
上引发异常并显示以下消息:
Microsoft.Data.SqlClient.SqlException (0x80131904): Cannot open database "MyTestDb" requested by the login. The login failed.
Login failed for user ''.
如果我在两个 using 块之间添加一个 Thread.Sleep(10_000);
,则不会抛出异常。
using (var sqlConnection = new SqlConnection(@"Data Source=(localdb)\MSSQLLocalDB;Integrated Security=True"))
{
sqlConnection.Open();
new SqlCommand("USE MASTER", sqlConnection).ExecuteNonQuery();
try
{
new SqlCommand($"ALTER DATABASE [MyTestDb] SET SINGLE_USER WITH ROLLBACK IMMEDIATE", sqlConnection).ExecuteNonQuery();
new SqlCommand($"DROP DATABASE [MyTestDb]", sqlConnection).ExecuteNonQuery();
}
catch (SqlException e)
{
// We get an error if there is no Database. This happens the very first time a test gets executed on a machine
}
new SqlCommand($"CREATE DATABASE [MyTestDb];", sqlConnection).ExecuteNonQuery();
new SqlCommand($"ALTER DATABASE [MyTestDb] SET ALLOW_SNAPSHOT_ISOLATION ON;", sqlConnection).ExecuteNonQuery();
new SqlCommand($"ALTER DATABASE [MyTestDb] SET READ_COMMITTED_SNAPSHOT ON;", sqlConnection).ExecuteNonQuery();
}
Thread.Sleep(10_000); // <-- exception will NOT be thrown
using (var creationConnection = new SqlConnection(@$"Data Source=(localdb)\MSSQLLocalDB;Integrated Security=True;Initial Catalog=MyTestDb"))
{
creationConnection.Open();
using (var context = new MyDbContext(/*some DbContextOptions here... */))
{
context.Database.Migrate();
}
}
我假设数据库 MyTestDb
未在 creationConnection.Open();
就绪并抛出错误。
有没有办法检查数据库创建是否完成?
你可以这样做:
SELECT [collation_name] FROM sys.databases WHERE name = 'MyTestDb';
如果collation_name有值(不为空),则数据库在线。
我在一个项目中使用 SQL 服务器作为数据库以及 Entity Framework Core 3.1。对于单元测试/集成测试,我们使用 LocalDB。
为确保 LocalDB 数据库处于正确的迁移状态,我们删除并重新创建测试数据库。
看起来像这样:
using (var sqlConnection = new SqlConnection(@"Data Source=(localdb)\MSSQLLocalDB;Integrated Security=True"))
{
sqlConnection.Open();
new SqlCommand("USE MASTER", sqlConnection).ExecuteNonQuery();
try
{
new SqlCommand($"ALTER DATABASE [MyTestDb] SET SINGLE_USER WITH ROLLBACK IMMEDIATE", sqlConnection).ExecuteNonQuery();
new SqlCommand($"DROP DATABASE [MyTestDb]", sqlConnection).ExecuteNonQuery();
}
catch (SqlException e)
{
// We get an error if there is no database. This happens the very first time a test gets executed on a machine
}
new SqlCommand($"CREATE DATABASE [MyTestDb];", sqlConnection).ExecuteNonQuery();
new SqlCommand($"ALTER DATABASE [MyTestDb] SET ALLOW_SNAPSHOT_ISOLATION ON;", sqlConnection).ExecuteNonQuery();
new SqlCommand($"ALTER DATABASE [MyTestDb] SET READ_COMMITTED_SNAPSHOT ON;", sqlConnection).ExecuteNonQuery();
}
using (var creationConnection = new SqlConnection(@$"Data Source=(localdb)\MSSQLLocalDB;Integrated Security=True;Initial Catalog=MyTestDb"))
{
creationConnection.Open(); // <-- Problematic exception here
using (var context = new MyDbContext(/*some DbContextOptions here... */))
{
context.Database.Migrate();
}
}
这将在 creationConnection.Open();
上引发异常并显示以下消息:
Microsoft.Data.SqlClient.SqlException (0x80131904): Cannot open database "MyTestDb" requested by the login. The login failed.
Login failed for user ''.
如果我在两个 using 块之间添加一个 Thread.Sleep(10_000);
,则不会抛出异常。
using (var sqlConnection = new SqlConnection(@"Data Source=(localdb)\MSSQLLocalDB;Integrated Security=True"))
{
sqlConnection.Open();
new SqlCommand("USE MASTER", sqlConnection).ExecuteNonQuery();
try
{
new SqlCommand($"ALTER DATABASE [MyTestDb] SET SINGLE_USER WITH ROLLBACK IMMEDIATE", sqlConnection).ExecuteNonQuery();
new SqlCommand($"DROP DATABASE [MyTestDb]", sqlConnection).ExecuteNonQuery();
}
catch (SqlException e)
{
// We get an error if there is no Database. This happens the very first time a test gets executed on a machine
}
new SqlCommand($"CREATE DATABASE [MyTestDb];", sqlConnection).ExecuteNonQuery();
new SqlCommand($"ALTER DATABASE [MyTestDb] SET ALLOW_SNAPSHOT_ISOLATION ON;", sqlConnection).ExecuteNonQuery();
new SqlCommand($"ALTER DATABASE [MyTestDb] SET READ_COMMITTED_SNAPSHOT ON;", sqlConnection).ExecuteNonQuery();
}
Thread.Sleep(10_000); // <-- exception will NOT be thrown
using (var creationConnection = new SqlConnection(@$"Data Source=(localdb)\MSSQLLocalDB;Integrated Security=True;Initial Catalog=MyTestDb"))
{
creationConnection.Open();
using (var context = new MyDbContext(/*some DbContextOptions here... */))
{
context.Database.Migrate();
}
}
我假设数据库 MyTestDb
未在 creationConnection.Open();
就绪并抛出错误。
有没有办法检查数据库创建是否完成?
你可以这样做:
SELECT [collation_name] FROM sys.databases WHERE name = 'MyTestDb';
如果collation_name有值(不为空),则数据库在线。