Si c'était moi (quand c'est moi...) :
Vous ne voulez pas particulièrement essayer de faire fonctionner les fichiers de base de données en les copiant et en les attachant - il y a des raisons pour lesquelles vous pourriez vouloir le faire, mais je pense qu'il s'agit d'exceptions plutôt que de règles.
En conséquence, ce que vous devez faire est de créer un script de création de la base de données, c'est-à-dire d'utiliser SQL DDL pour créer la base de données, les tables et tous les autres éléments de votre schéma.
Pratiquement tout ce dont vous avez besoin pour vous permettre de le faire, ce sont les droits appropriés sur l'instance de serveur, puis une chaîne de connexion (que vous pouvez probablement créer en dehors du nom du serveur/de l'instance).
À partir d'ici :
- Existe-t-il une base de données ? Sinon, créez-le.
- S'il existe une base de données, est-ce la bonne version de schéma ? S'il est trop bas, mettez-le à jour ou informez l'utilisateur et revenez gracieusement en fonction de la façon dont vous souhaitez que les choses fonctionnent également. S'il est trop élevé, revenez en arrière et indiquez qu'une version mise à jour de l'application est requise
- Tout est comme il se doit, continuez.
D'un point de vue code :méthode pour déterminer si une base de données existe; méthode pour créer une base de données "vide" standard avec une table de version et un numéro de version de 0 ; méthodes pour amener le schéma à la version actuelle en exécutant le DDL approprié (nous encodons le nôtre en C # car il offre plus de flexibilité, mais vous pouvez également exécuter des scripts DDL en séquence).
Existe-t-il :
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;
}
Créer une nouvelle base de données :
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();
}
}
Le code de mise à jour est un peu plus complexe mais fonctionne essentiellement comme ceci :
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
);
Le tout enveloppé dans une transaction par mise à jour - de sorte que si la mise à jour échoue, vous devez laisser la base de données dans un bon état connu.
Pourquoi le faire de cette façon (dans le code, ce qui n'est pas sans essais ?) Eh bien, le résultat final est un degré élevé de confiance dans le fait que le schéma auquel votre application parle est le schéma auquel votre application s'attend à parler... les bonnes tables, bonnes colonnes (dans le bon ordre, qui sont du bon type et de la bonne longueur), etc, etc. et que cela continuera d'être le cas dans le temps.
Désolé si c'est un peu long - mais c'est quelque chose qui me tient à coeur...