Codifique a primeira cadeia de conexão personalizada e as migrações sem usar IDbContextFactory
Eu estou tentando escrever um fácil de entenderDBContext
classe que recebe uma string de conexão personalizada, pode executar migrações e permite gerar migrações usando o Gerenciador de Pacotes.
Eu pareço estar andando em círculos.
Consegui fazê-lo funcionar usando código que me parece horrível. Eu documentei isso na minha respostaEsta questão na cadeia de conexão e migrações.
A resposta de Radek parece muito melhor do que a minha, mas acho que quando eu implemento e depois tento criar uma migração no Gerenciador de Pacotes, recebo a mensagem
O contexto de destino 'DataLayer.Context' não é construtível. Adicione um construtor padrão ou forneça uma implementação de IDbContextFactory.
OndeDataLayer.Context
é minha classe de contexto.
Eu não quero fornecer uma implementação deIDbContextFactory
(e a resposta de Radek parece indicar que não é necessário)
ATUALIZAR:
Eu posso gerar uma migração se eu incluir um construtor sem parâmetro. Por exemplo
public Context() : base("ConnectionStringName") { }
Para minha criação de contexto, eu passo o nome da string de conexão no app.config
public Context(string connString) : base(connString)
{
Database.SetInitializer(new CustomInitializer());
Database.Initialize(true);
}
Por fim, posso gerar migrações e executar migrações para bancos de dados que o usuário seleciona.
NO ENTANTO: Quando eu derrubar o banco de dados e, em seguida, executar o meu aplicativo, tenho problemas.
O código inicializador que estou usando, no link acima, é
public class CustomInitializer : IDatabaseInitializer<Context>
{
public void InitializeDatabase(Context context)
{
try
{
if (!context.Database.Exists())
{
context.Database.Create();
}
else
{
if (!context.Database.CompatibleWithModel(false))
{
var configuration = new Configuration();
var migrator = new DbMigrator(configuration);
migrator.Configuration.TargetDatabase =
new DbConnectionInfo(context.Database.Connection.ConnectionString);
IEnumerable<string> migrations = migrator.GetPendingMigrations();
foreach (string migration in migrations)
{
var scriptor = new MigratorScriptingDecorator(migrator);
string script = scriptor.ScriptUpdate(null, migration);
context.Database.ExecuteSqlCommand(script);
}
}
}
}
catch (Exception ex)
{
}
}
}
Quando eu derrubar o banco de dados, um novo é criado, mas não tem tabelas. Isso porque meu código de criação de tabela está na minha primeira migração.
Então o código dentro do!context.Database.CompatibleWithModel(false)
condição não é executada.
No entanto, infelizmente, o código também não é executado na segunda vez quando deveria ter o metadatamodel.
Agora, para tentar fazer a migração funcionar ...
SADNESS: Não com o inicializador personalizado do Radek até agora.
A partir dos comentários de NSGaga, recorri a sair do aplicativo se eu mudar de conexão.
var master = new myMDIForm();
master.ConnectionType = connectionType; // being an enum of the different connection names in app.config
while (master.ConnectionType != ConnectionType.None )
{
Application.Run(master);
}