Como criar um arquivo de database SQL 2008 “incorporado”, se ele não existir?

Eu criei um aplicativo de database usando C #, ADO.Net e um arquivo de database MS SQL 2008 incorporado (anexado ao MS SQL 2008 Express) que criei no Server Management Studio. Alguém pode me apontar para um recurso que descreve como eu posso criar programaticamente o arquivo de database se ele estiver faltando (por exemplo, logo após o meu aplicativo ser instalado)?

Se fosse eu (quando for eu …):

Você não quer particularmente tentar fazer com que os arquivos do database funcionem, copiando-os e anexando-os – há razões pelas quais você pode querer, mas acredito que sejam exceções em vez de regras.

Assim, o que você precisa fazer é criar script do database, ou seja, usar o SQL DDL para criar o database e as tabelas e todas as outras coisas no seu esquema.

Praticamente tudo que você precisa para permitir que você faça isso são os direitos apropriados para a instância do servidor e, em seguida, uma seqüência de conexão (que você provavelmente pode construir além do nome do servidor / instância).

Daqui:

  1. Existe um database? Se não criá-lo.
  2. Se houver um database, a versão correta do esquema? Se for muito baixo, atualize-o ou avise o usuário e retorne com graça, dependendo de como você deseja que as coisas funcionem. Se for muito alto, recue e avise que é necessária uma versão atualizada do aplicativo
  3. Tudo é como deveria ser, continue.

De um ponto de vista de código: método para determinar se existe um database; método para criar um database padrão “vazio” com uma tabela de versão e um número de versão de 0; methods para trazer o esquema até a versão atual executando o DDL apropriado (nós codificamos o nosso em C # porque ele fornece mais flexibilidade, mas você pode igualmente executar scripts DDL em sequência).

Isto existe:

public virtual bool Exists() { bool exists = false; string masterConnectionString = this.CreateConnectionString(this.Server, this.FailoverServer, "master"); this.DBConnection.ConnectionString = masterConnectionString; this.DBConnection.Open(); try { SqlCommand cmd = new SqlCommand(); cmd.Connection = this.DBConnection; cmd.CommandText = "SELECT COUNT(name) FROM sysdatabases WHERE name = @DBName"; cmd.Parameters.AddWithValue("@DBName", this.DBName); exists = (Convert.ToInt32(cmd.ExecuteScalar()) == 1); } finally { this.DBConnection.Close(); } return exists; } 

Crie um novo database:

  public virtual void CreateNew() { string createDDL = @"CREATE DATABASE [" + this.DBName + "]"; this.BuildMasterConnectionString(); this.DBConnection.Open(); try { this.ExecuteSQLStmt(createDDL, this.DefaultSQLTimeout, null); } finally { this.DBConnection.Close(); } createDDL = @" CREATE TABLE AAASchemaVersion ( Version int NOT NULL, DateCreated datetime NOT NULL, Author nvarchar(30) NOT NULL, Notes nvarchar(MAX) NULL ); ALTER TABLE AAASchemaVersion ADD CONSTRAINT PK_Version PRIMARY KEY CLUSTERED ( Version ); INSERT INTO AAASchemaVersion (Version, DateCreated, Author, Notes) VALUES (0, GETDATE(), 'James Murphy', 'Empty Database') "; this.BuildConnectionString(); this.ConnectionString += ";pooling=false"; this.DBConnection.Open(); try { this.ExecuteSQLStmt(createDDL, this.DefaultSQLTimeout, null); } catch (Exception ex) { throw new Exception("Exception while creating / initialising AAASchemaVersion", ex); } finally { this.DBConnection.Close(); } } 

O código de atualização é um pouco mais complexo, mas basicamente executa coisas como esta:

 CREATE TABLE AuditUser ( ID int IDENTITY(1,1) NOT NULL, UserSourceTypeID tinyint NOT NULL, DateCreated smalldatetime NOT NULL, UserName nvarchar(100) NOT NULL ); ALTER TABLE AuditUser ADD CONSTRAINT PK_AuditUser PRIMARY KEY CLUSTERED ( ID ), CONSTRAINT [FK_AuditUser_UserSourceType] FOREIGN KEY ( UserSourceTypeID ) REFERENCES UserSourceType ( ID ); 

Tudo embrulhado em uma transação por atualização – de modo que, se a atualização falhar, você deve deixar o database como um bom estado conhecido.

Por que é assim (no código, o que não é isento de testes?), O resultado final é um alto grau de confiança de que o esquema com o qual seu aplicativo está falando é o esquema com o qual seu aplicativo espera conversar … tabelas corretas, colunas da direita (na ordem certa, que são do tipo certo e do comprimento certo), etc, etc. e que isso continuará a ser o caso ao longo do tempo.

Desculpas se isso é um pouco longo – mas isso é algo que eu estou muito interessado em …

Se o “MS SQL incorporado” for um “Microsoft SQL Server Compact 3.5”:

 using (SqlCeEngine sqlCeEngine = new SqlCeEngine(connectionString)) sqlCeEngine.CreateDatabase(); 
    Intereting Posts