在访问以编程方式创建的数据库之前等待

我正在使用SqlClient在我的程序中创建一个数据库。 该应用程序需要定期创建一个新的数据库,但结构是相同的。 所以我在一个文件中有创建脚本,我一次执行一行。 当我完成后,我只是关闭它,因为应用程序的另一部分(使用SubSonic编写)将操纵新创建的数据库。

我遇到的问题是,即使在成功创建数据库之后,当我去访问它时,我得到一个exception,告诉我登录失败。 一段时间后,此访问成功。 我把它缩小到5秒 – 任何更少的东西导致失败,在5秒它工作正常。 下面的代码certificate了(以一种人为的方式),但它也向我certificate了SubSonic根本没有涉及这个问题。

这是我需要忍受的东西,还是有些东西我做得不对?

我的代码是:

using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.IO; using System.Data; using System.Data.SqlClient; namespace SqlConnTest { class Program { static void Main(string[] args) { var x = new ContentDB(); if (x.IsNew) { x.Dispose(); System.Threading.Thread.Sleep(4500); Console.WriteLine("Second time around"); x = new ContentDB(); } Console.WriteLine("All done"); Console.ReadKey(); } } class ContentDB : IDisposable { private bool disposed = false; public void Dispose() { Dispose(true); } protected virtual void Dispose(bool disposing) { if (!this.disposed) { if (disposing) { } disposed = true; } } public bool IsNew {get;set;} public ContentDB() { SqlConnection conn = new SqlConnection("Data Source=.\\SQLEXPRESS;Initial Catalog=Arch;Persist Security Info=False;User ID=Brunner;Password=Brunn3r1x"); try { conn.Open(); } catch (SqlException ex) { Console.WriteLine("Arch database needs to be created. {0}", ex.Message); IsNew = true; } finally { if (conn.State == ConnectionState.Open) conn.Close(); conn.Dispose(); } if (IsNew) CreateDB(); } private void CreateDB() { using (var SqlScriptReader = new StreamReader("c:\\temp\\create.sql")) { var conn = new SqlConnection("Data Source=.\\SQLEXPRESS;Initial Catalog=master;Persist Security Info=False;User ID=Brunner;Password=Brunn3r1x"); conn.Open(); string SqlCmd = SqlScriptReader.ReadLine(); while (SqlCmd != null && SqlCmd != String.Empty) { try { var cmd = new SqlCommand(SqlCmd,conn); cmd.ExecuteNonQuery(); cmd.Dispose(); } catch (SqlException ex) { Console.WriteLine("SQL command {0} failed,\n{1}", SqlCmd,ex.Message); } SqlCmd = SqlScriptReader.ReadLine(); } if (conn.State == ConnectionState.Open) conn.Close(); conn.Dispose(); } Console.WriteLine("CreateDB finished"); } } 

}

并且.SQL文件的内容是:

 USE [master] CREATE DATABASE [Arch] ON PRIMARY ( NAME = N'Arch', FILENAME = N'C:\temp\Arch.mdf', SIZE = 2048KB , MAXSIZE = UNLIMITED, FILEGROWTH = 1024KB ) LOG ON ( NAME = N'Arch_log', FILENAME = N'C:\temp\Arch_log.ldf' , SIZE = 1024KB , MAXSIZE = 2048GB , FILEGROWTH = 10%) USE [Arch] CREATE TABLE [dbo].[RptContent] ([RptContentID] [int] IDENTITY(1,1) NOT NULL, [RptContentBLOB] [varbinary](max) NOT NULL CONSTRAINT [PK_RptContent] PRIMARY KEY CLUSTERED ([RptContentID] ASC ) WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]) ON [PRIMARY] 

当我在没有Arch数据库的情况下运行它时,我得到:

 Arch database needs to be created. Cannot open database "Arch" requested by the login. The login failed. Login failed for user 'Brunner'. CreateDB finished Second time around Arch database needs to be created. Cannot open database "Arch" requested by the login. The login failed. Login failed for user 'Brunner'. SQL command CREATE DATABASE [Arch] ON PRIMARY ( NAME = N'Arch', FILENAME = N'C: \temp\Arch.mdf', SIZE = 2048KB , MAXSIZE = UNLIMITED, FILEGROWTH = 1024KB ) LOG ON ( NAME = N'Arch_log', FILENAME = N'C:\temp\Arch_log.ldf' , SIZE = 1024KB , M AXSIZE = 2048GB , FILEGROWTH = 10%) failed, Database 'Arch' already exists. Choose a different database name. SQL command CREATE TABLE [dbo].[RptContent] ([RptContentID] [int] IDENTIT Y(1,1) NOT NULL, [RptContentBLOB] [varbinary](max) NOT NULL CONSTRAINT [PK_RptContent] PRIMARY KEY CLUSTERED ([RptContentID] ASC ) WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]) ON [PRIMARY] failed, There is already an object named 'RptContent' in the database. CreateDB finished All done 

以5000的睡眠运行它给了我:

 Arch database needs to be created. Cannot open database "Arch" requested by the login. The login failed. Login failed for user 'Brunner'. CreateDB finished Second time around All done 

如果Arch数据库已经存在则运行给出:

 All done 

对不起,如果这很长 – 我试图将其剥离到代码的简短版本,以certificate我正在做的事情和问题。

相反,线程hibernate,您可以执行此任务:创建一个搜索已创建数据库的循环,并在您找不到它时循环。

如何查找数据库是否存在: 如何检查SQL Server中是否存在数据库?

出于性能目的,您应该为每个循环放置一个计时器(如线程hibernate),而不是连续搜索。 你说平均时间是5秒,所以在每个1或2秒循环可能没问题!