Passe a string de conexão para o código DbContext

90

Como faço para passar uma string de conexão para o DbContext codificado pela estrutura da entidade? Minha geração de banco de dados funciona corretamente quando DbContext e a string de conexão em web.config estão no mesmo projeto e são nomeados da mesma forma. Mas agora preciso mover o DbContext para outro projeto, então estou testando a passagem de uma string de conexão para ele da seguinte maneira:

Modelo e Contexto

public class Dinner
{
    public int DinnerId { get; set; }
    public string Title { get; set; }
}

public class NerdDinners : DbContext
{
    public NerdDinners(string connString)
        : base(connString)
    {
    }
    public DbSet<Dinner> Dinners { get; set; }
}

Açao

    public ActionResult Index()
    {
        var db = new NerdDinners(ConfigurationManager.ConnectionStrings["NerdDinnerDb"].ConnectionString);

        var dinners = (from d in db.Dinners
                      select d).ToList();
        return View(dinners);
    }

Web.Config

<connectionStrings>
  <add name="NerdDinnerDb" connectionString="Data Source=|DataDirectory|NerdDinners.sdf" providerName="System.Data.SqlServerCe.4.0"/>    
</connectionStrings>

Se eu definir um ponto de interrupção na ação e analisar o db, a string de conexão está lá, mas não cria ou encontra o banco de dados ou nada.

Ocorreu um erro relacionado à rede ou específico da instância ao estabelecer uma conexão com o SQL Server. O servidor não foi encontrado ou não estava acessível. Verifique se o nome da instância está correto e se o SQL Server está configurado para permitir conexões remotas. (provedor: Provedor de Pipes Nomeados, erro: 40 - Não foi possível abrir uma conexão com o SQL Server)

Shawn Mclean
fonte
Tem certeza absoluta de que está se conectando ao servidor correto? O erro é uma exceção típica do SQL Server / Express. Não parece que você está conectado a um banco de dados Sql CE ... e o EF Code primeiro criará o banco de dados se ele não existir ... a menos que o caminho não possa ser encontrado, talvez ...
Steven K.
Então, basicamente, o erro do OP foi enviar toda a cadeia de conexões para o construtor DbContaxt, em vez de apenas o nome. Como diz a documentação: "DbContext (String) Constrói uma nova instância de contexto usando a string fornecida como o nome ou string de conexão para o banco de dados"
Göran Roseen

Respostas:

85

Um pouco tarde para o jogo aqui, mas outra opção é:

public class NerdDinners : DbContext
{
    public NerdDinners(string connString)
    {
        this.Database.Connection.ConnectionString = connString;
    }
    public DbSet<Dinner> Dinners { get; set; }
}
Bitfiddler
fonte
2
Oi! Essa foi a única solução que me levou a algum lugar. Meu problema é que eu gostaria de obter as configurações do meu arquivo de configuração do Azure em vez de web.config. Ainda assim, esta forma não funciona porque a configuração 'Provedor' está faltando (é definida como um atributo no web.config). Alguma ideia?
usuário
1
Excelente resposta! A única alteração feita foi remover o parâmetro connString e, em seguida, usar a string de conexão salva nas configurações do aplicativo .... this.Database.Connection.ConnectionString = Properties.Settings.Default.ConnectionString
helpfulBee
Como posso passar o objeto connString e DbCompiledModel ao mesmo tempo como parâmetro?
Behzad Ebrahimi
Agradável. Apenas "isso" é redundante, você pode removê-lo.
tocqueville
1
se o seu módulo de classe inclui Manual changes to this file will be overwritten if the code is regenerated.no cabeçalho, então alguém pode querer implementar isso em uma classe parcial de acordo com Classes e métodos parciais (Guia de programação C #)
woodvi
58

Depois de ler a documentação, preciso passar o nome da string de conexão:

var db = new NerdDinners("NerdDinnerDb");
Shawn Mclean
fonte
Coloquei isso no meu construtor e tornei-o uma constante pública caso seja necessário para referência em outro lugar.
Tony Wall de
37

Pensei em adicionar este trecho para pessoas que procuram "Como passar uma string de conexão para um DbContext": você pode construir uma string de conexão para seu armazenamento de dados subjacente e passar toda a string de conexão para o construtor do seu tipo derivado de DbContext .

(Reutilizando o código do @Lol Coder) Modelo e contexto

public class Dinner
{
    public int DinnerId { get; set; }
    public string Title { get; set; }
}

public class NerdDinners : DbContext
{
    public NerdDinners(string connString)
        : base(connString)
    {
    }
    public DbSet<Dinner> Dinners { get; set; }
}

Então, digamos que você construa uma string de conexão Sql usando o SqlConnectioStringBuilder da seguinte maneira:

SqlConnectionStringBuilder builder = new SqlConnectionStringBuilder(GetConnectionString());

Onde o método GetConnectionString constrói a string de conexão apropriada e o SqlConnectionStringBuilder garante que a string de conexão esteja sintaticamente correta; você pode então instanciar seu conetxt db assim:

var myContext = new NerdDinners(builder.ToString());
Sudhanshu Mishra
fonte
4
Para codificar realmente a string de conexão que fiz:public TestAppContext() : base("Data Source=server.company.com;Initial Catalog=SomeDB;Integrated Security=True") { }
Elijah W. Gagne
28

Em seu DbContext, crie um construtor padrão para seu DbContext e herde a base desta forma:

    public myDbContext()
        : base("MyConnectionString")  // connectionstring name define in your web.config
    {
    }
Kinh Pham
fonte
1
No meu caso, ele cria um banco de dados chamado MyConnectionString... (sim, a string de conexão existe). Eu tenho que colocar name=MyConnectionString.
Matthieu Charbonnier
2

Se você estiver construindo a string de conexão dentro do aplicativo, você deve usar o comando connString. Se você estiver usando uma string de conexão na configuração da web. Então você usa o "nome" dessa string.

MKunstman
fonte
2

Eu tenho um pequeno exemplo de solução para esse problema.

MyDBContext.cs

 public MyDBContext(DBConnectionType ConnectionType) //: base("ConnMain")
  {
      if(ConnectionType==DBConnectionType.MainConnection)
       {
         this.Database.Connection.ConnectionString = ConfigurationManager.ConnectionStrings["ConnMain"].ConnectionString;
       }
      else if(ConnectionType==DBConnectionType.BackupConnection)
       {
         this.Database.Connection.ConnectionString = ConfigurationManager.ConnectionStrings["ConnBackup"].ConnectionString;
       }
  }

MyClass.cs

public enum DBConnectionType
 {
    MainConnection=0,
    BackupConnection=1
 }

frmMyForm.cs

 MyDBContext db = new MyDBContext(DBConnectionType.MainConnection);
                               //or
//MyDBContext db = new MyDBContext(DBConnectionType.BackupConnection);
Durgesh Pandey
fonte
1

Verifique a sintaxe da string de conexão no web.config. Deve ser algo comoConnectionString="Data Source=C:\DataDictionary\NerdDinner.sdf"

kmerkle
fonte
A string de conexão funciona quando ambos usam o mesmo nome no mesmo projeto.
Shawn Mclean
Ele não funciona quando desejo passá-lo manualmente para o DbConext
Shawn Mclean
A string de conexão está bem, o caminho não precisa ser absoluto.
Steven K.
1

Ao usar um modelo EF, tenho uma string de conexão em cada projeto que consome o modelo EF. Por exemplo, eu tenho um modelo EF EDMX em uma biblioteca de classes separada. Eu tenho uma string de conexão no meu projeto web (mvc) para que ele possa acessar o banco de dados EF.

Eu também tenho outro projeto de teste de unidade para testar os repositórios. Para que os repositórios acessem o banco de dados EF, o arquivo app.config do projeto de teste tem a mesma string de conexão.

As conexões de banco de dados devem ser configuradas, não codificadas, IMO.

danludwig
fonte
2
Preciso passar manualmente a string de conexão por código. Estou usando injeção de dependência.
Shawn Mclean
0

Não consigo ver nada de errado com seu código, eu uso SqlExpress e funciona bem quando uso uma string de conexão no construtor.

Você criou uma pasta App_Data em seu projeto, não é?

Lee Smith
fonte
0

Para qualquer um que veio aqui tentando descobrir como definir a string de conexão dinamicamente e teve problemas com as soluções acima (como "O formato da string de inicialização não está de acordo com a especificação começando no índice 0") ao configurar a string de conexão no construtor. Veja como consertar:

public static string ConnectionString
{
    get {
        if (ConfigurationManager.AppSettings["DevelopmentEnvironment"] == "true")
            return ConfigurationManager.ConnectionStrings["LocalDb"].ConnectionString;
        else
            return ConfigurationManager.ConnectionStrings["ExternalDb"].ConnectionString;
    }
}

public ApplicationDbContext() : base(ConnectionString)
{
}
Thiago Araujo
fonte
0

a partir daqui

 protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
    {
      optionsBuilder.UseSqlServer(ConfigurationManager.ConnectionStrings["BloggingDatabase"].ConnectionString);
    }

note que você pode precisar adicionar Microsoft.EntityFrameworkCore.SqlServer

Abdullah Tahan
fonte