Если бы это был я (когда это я ...):
Вы не особенно хотите пытаться заставить файлы базы данных работать, копируя их и прикрепляя их - есть причины, по которым вы можете захотеть, но я считаю, что это скорее исключения, чем правила.
Соответственно, вам нужно создать сценарий для создания базы данных, т. Е. Использовать SQL DDL для создания базы данных, таблиц и всего остального в вашей схеме.
Практически все, что вам нужно для того, чтобы сделать это, - это соответствующие права на экземпляр сервера и затем строку подключения (которую вы, вероятно, можете построить отдельно от имени сервера / экземпляра).
Отсюда:
- Есть ли база данных? Если не создать его.
- Если база данных существует, это правильная версия схемы? Если оно слишком низкое, либо обновите его, либо советуйте пользователю, и отступайте корректно, в зависимости от того, как вы хотите, чтобы все тоже работало. Если слишком высокий, просто вернитесь и сообщите, что требуется обновленная версия приложения
- Все как положено, продолжай.
С точки зрения кода: метод определения, существует ли база данных; способ создания стандартной «пустой» базы данных с таблицей версий и номером версии 0; методы для приведения схемы к текущей версии, запустив соответствующий DDL (мы кодируем наш в C #, потому что он обеспечивает большую гибкость, но вы также можете запускать сценарии DDL в последовательности).
Существует ли оно:
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;
}
Создать новую базу данных:
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();
}
}
Код обновления немного сложнее, но в основном работает так:
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
);
Все завернуто в транзакции на обновление - так что, если обновление завершится неудачно, вы должны покинуть базу данных в известном исправном состоянии.
Почему так (в коде, который не обходится без испытаний?), Конечный результат - высокая степень уверенности в том, что схема, с которой работает ваше приложение, - это схема, с которой ваше приложение ожидает общаться ... правильные таблицы, правильные столбцы (в правильном порядке, правильного типа и правильной длины) и т. д. и т. д., и что со временем это будет иметь место.
Прошу прощения, если это немного долго - но это то, что я очень заинтересован ...