Jika itu aku (saat itu aku...):
Anda tidak terlalu ingin mencoba membuat file database berfungsi dengan menyalinnya dan melampirkannya - ada beberapa alasan mengapa Anda mungkin ingin melakukannya, tetapi saya yakin ini adalah pengecualian daripada aturan.
Oleh karena itu, yang perlu Anda lakukan adalah membuat skrip database, yaitu menggunakan SQL DDL untuk membuat database dan tabel dan semua hal lain dalam skema Anda.
Hampir semua yang Anda perlukan untuk memungkinkan Anda melakukan ini adalah hak yang sesuai untuk instance server dan kemudian string koneksi (yang mungkin dapat Anda buat selain dari nama server/instance).
Dari sini:
- Apakah ada databasenya? Jika tidak, buatlah.
- Jika ada database, apakah versi skema yang benar? Jika terlalu rendah, perbarui atau beri tahu pengguna dan mundur dengan anggun tergantung pada bagaimana Anda ingin semuanya bekerja. Jika terlalu tinggi, mundur saja dan sarankan agar versi aplikasi yang diperbarui diperlukan
- Semuanya sebagaimana mestinya, lanjutkan.
Dari sudut pandang kode:metode untuk menentukan apakah database ada; metode untuk membuat database "kosong" standar dengan tabel versi dan nomor versi 0; metode untuk membawa skema ke versi saat ini dengan menjalankan DDL yang sesuai (kami mengkodekan skema kami ke dalam C# karena memberikan lebih banyak fleksibilitas tetapi Anda juga dapat menjalankan skrip DDL secara berurutan).
Apakah itu ada:
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;
}
Buat basis data baru:
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();
}
}
Kode pembaruan sedikit lebih rumit tetapi pada dasarnya menjalankan hal-hal seperti ini:
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
);
Semua terbungkus dalam transaksi per pembaruan - sehingga jika pembaruan gagal, Anda harus meninggalkan database dalam keadaan baik.
Mengapa melakukannya dengan cara ini (dalam kode, yang bukan tanpa uji coba?) hasil akhirnya adalah tingkat kepercayaan yang tinggi bahwa skema yang digunakan aplikasi Anda adalah skema yang diharapkan untuk diajak bicara oleh aplikasi Anda... tabel yang benar, kolom kanan (dalam urutan yang benar, yaitu jenis yang tepat dan panjang yang tepat), dll, dll. dan hal ini akan terus terjadi seiring waktu.
Maaf jika ini agak panjang - tapi ini adalah sesuatu yang saya sangat tertarik...