我們在一個相對較新的項目中使用了EF 6 Code First Migrations(即沒有太多混亂的情況需要處理)。此外,由於這是一個「企業-y」的應用,我們有我們的目標數據庫的一些具體部署規則:如何使用自定義配置步驟配置EF數據庫?
- 所有的應用程序級別的數據訪問必須通過特定的數據庫用戶(
app-user
) - 此完成
app-user
沒有權限來創建新的數據庫
因此,爲了正確地提供這種應用一個新的目標數據庫,我們需要:
CREATE DATABASE [database_name] CONTAINMENT = PARTIAL
CREATE USER [app-user] WITH PASSWORD=N'[email protected]'
- (加上指定特定的數據庫角色,這個新的用戶)
我希望通過編寫自定義IDatabaseInitializer<TContext>
,從事這項運動,但似乎我不能最基本的數據庫在正確的點進行初始化。
概念,我想這樣做:
- 有用於對數據庫的讀/寫訪問一個連接字符串,使用「控制器」
app-user
用戶 - 有一個單獨的連接字符串僅用於供應數據庫,使用更多的特權憑證
我曾嘗試使用的代碼看起來有點像這樣:
internal class ProvisionThenMigrateInitializer<TContext, TConfiguration>
: MigrateDatabaseToLatestVersion<TContext, TConfiguration>, IDatabaseInitializer<TContext>
where TContext : DbContext
where TConfiguration : DbMigrationsConfiguration<TContext>, new()
{
private readonly DbMigrationsConfiguration _readWriteConfiguration;
private readonly string _provisioningConnectionName;
public ProvisionThenMigrateInitializer(string readWriteConnectionName, string provisioningConnectionName)
{
_provisioningConnectionName = provisioningConnectionName;
_readWriteConfiguration = new TConfiguration
{
TargetDatabase = new DbConnectionInfo(readWriteConnectionName)
};
}
void IDatabaseInitializer<TContext>.InitializeDatabase(TContext context)
{
if (context.Database.Exists())
{
if (!context.Database.CompatibleWithModel(false))
{
DbMigrator migrator = new DbMigrator(_readWriteConfiguration);
migrator.Update();
}
}
else
{
// TODO - Create the DB and user here...
string[] sqlStatements =
{
"CREATE DATABASE [database_name] CONTAINMENT = PARTIAL ",
"USE [database_name]",
"CREATE USER [app_user] WITH PASSWORD=N'[email protected]'",
"USE [database_name]",
"ALTER ROLE [db_datareader] ADD MEMBER [app_user]",
"ALTER ROLE [db_datawriter] ADD MEMBER [app_user]",
};
string connectionString = ConfigurationManager.ConnectionStrings[_provisioningConnectionName].ConnectionString;
SqlConnection sqlConnection = new SqlConnection(connectionString);
foreach (SqlCommand command in sqlStatements.Select(sqlStatement => new SqlCommand(sqlStatement, sqlConnection)))
{
command.ExecuteNonQuery();
}
context.Database.Create();
Seed(context);
context.SaveChanges();
}
}
我將在我的DbContext
派生類的靜態構造函數使用初始化:
Database.SetInitializer(new ProvisionThenMigrateInitializer<Context, Configuration>(
DOMAIN_MODEL_CONNECTION_STRING_NAME,
DOMAIN_MODEL_PROVISIONING_CONNECTION_STRING_NAME));
然而,當我試圖用我看中新的自定義數據庫初始化,通過以下方式,它只是普通的沒有按「T工作:
using (Context c = new Context())
{
try
{
c.Database.Initialize(true);
}
catch (Exception e)
{
Console.WriteLine(e);
}
}
我想,到時候我嘗試調用c.Database.Initialize(true)
EF已經試圖連接到數據庫(使用app_user
憑證,而不是「供應的憑證),將connecti試圖失敗,我們炸燬了。
實際上是否可以使用EF 6,Code First和Migrations來實現我的數據庫的配置?如果是這樣,我做錯了什麼?
非常感謝。
你應該能夠有特殊的聯繫,做你自己。 –