Pasar la cadena de conexión al código DbContext primero

92

¿Cómo paso una cadena de conexión al código DbContext primero del marco de la entidad? La generación de mi base de datos funciona correctamente cuando tanto DbContext como la cadena de conexión en web.config están en el mismo proyecto y tienen el mismo nombre. Pero ahora necesito mover el DbContext a otro proyecto, así que estoy probando pasarle una cadena de conexión de la siguiente manera:

Modelo y 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; }
}

Acción

    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>

Si establezco un punto de interrupción en la acción y analizo db, la cadena de conexión está allí, pero no crea ni encuentra la base de datos ni nada.

Se produjo un error relacionado con la red o específico de la instancia al establecer una conexión con SQL Server. El servidor no se encontró o no estaba accesible. Verifique que el nombre de la instancia sea correcto y que SQL Server esté configurado para permitir conexiones remotas. (proveedor: proveedor de canalizaciones con nombre, error: 40: no se pudo abrir una conexión a SQL Server)

Shawn Mclean
fuente
¿Está absolutamente seguro de que se está conectando al servidor correcto? El error es una excepción típica de SQL Server / Express. No suena como si estuviera conectado a una base de datos Sql CE ... y EF Code primero creará la base de datos si no existe ... a menos que no se pueda encontrar la ruta tal vez ...
Steven K.
Entonces, básicamente, el error de OP fue enviar la cadena de conexión completa al constructor DbContaxt, en lugar de solo el nombre. Como dice la documentación: "DbContext (String) Construye una nueva instancia de contexto utilizando la cadena dada como nombre o cadena de conexión para la base de datos"
Göran Roseen

Respuestas:

86

Un poco tarde para el juego aquí, pero otra opción es:

public class NerdDinners : DbContext
{
    public NerdDinners(string connString)
    {
        this.Database.Connection.ConnectionString = connString;
    }
    public DbSet<Dinner> Dinners { get; set; }
}
Bitfiddler
fuente
2
¡Hola! Esta fue la única solución que me llevó a alguna parte. Mi problema es que me gustaría tomar la configuración de mi archivo de configuración de Azure en lugar de web.config. Aún así, esta forma no funciona ya que falta la configuración 'Proveedor' (está configurada como un atributo en web.config). ¿Algunas ideas?
usuario
1
¡Excelente respuesta! El único cambio realizado fue eliminar el parámetro connString y luego usar la cadena de conexión guardada en la configuración de la aplicación .... this.Database.Connection.ConnectionString = Properties.Settings.Default.ConnectionString
helpfulBee
¿Cómo puedo pasar el objeto connString y DbCompiledModel al mismo tiempo que el parámetro?
Behzad Ebrahimi
Agradable. Solo "esto" es redundante, puede eliminarlo.
tocqueville
1
si su módulo de clase se incluye Manual changes to this file will be overwritten if the code is regenerated.en el encabezado, entonces es posible que desee implementar esto en una clase parcial según las clases y métodos parciales (Guía de programación de C #)
woodvi
59

Después de leer los documentos, tengo que pasar el nombre de la cadena de conexión en su lugar:

var db = new NerdDinners("NerdDinnerDb");
Shawn Mclean
fuente
Lo puse en mi constructor y lo convertí en una constante pública en caso de que sea necesario como referencia en otro lugar.
Tony Wall
37

Pensé en agregar este bit para las personas que vienen en busca de "Cómo pasar una cadena de conexión a un DbContext": puede construir una cadena de conexión para su almacén de datos subyacente y pasar la cadena de conexión completa al constructor de su tipo derivado de DbContext .

(Reutilización del código de @Lol Coder) Modelo y 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; }
}

Luego, digamos que construye una cadena de conexión Sql usando SqlConnectioStringBuilder así:

SqlConnectionStringBuilder builder = new SqlConnectionStringBuilder(GetConnectionString());

Donde el método GetConnectionString construye la cadena de conexión apropiada y el SqlConnectionStringBuilder asegura que la cadena de conexión sea sintácticamente correcta; A continuación, puede crear una instancia de su conetxt db así:

var myContext = new NerdDinners(builder.ToString());
Sudhanshu Mishra
fuente
4
Para codificar realmente la cadena de conexión que hice:public TestAppContext() : base("Data Source=server.company.com;Initial Catalog=SomeDB;Integrated Security=True") { }
Elijah W. Gagne
28

En su DbContext, cree un constructor predeterminado para su DbContext y herede la base así:

    public myDbContext()
        : base("MyConnectionString")  // connectionstring name define in your web.config
    {
    }
Kinh Pham
fuente
1
En mi caso, crea una base de datos llamada MyConnectionString... (sí, existe la cadena de conexión). Tengo que poner name=MyConnectionString.
Matthieu Charbonnier
2

Si está construyendo la cadena de conexión dentro de la aplicación, entonces usaría su comando de connString. Si está utilizando una cadena de conexión en el archivo web config. Luego usa el "nombre" de esa cadena.

MKunstman
fuente
2

Tengo un pequeño ejemplo de solución para ese 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
fuente
1

Verifique la sintaxis de su cadena de conexión en web.config. Debería ser algo comoConnectionString="Data Source=C:\DataDictionary\NerdDinner.sdf"

kmerkle
fuente
La cadena de conexión funciona cuando ambos usan el mismo nombre en el mismo proyecto.
Shawn Mclean
No funciona cuando quiero pasarlo manualmente a DbConext
Shawn Mclean
La cadena de conexión está bien, la ruta no necesita ser absoluta.
Steven K.
1

Cuando utilizo un modelo EF, tengo una cadena de conexión en cada proyecto que consume el modelo EF. Por ejemplo, tengo un modelo EF EDMX en una biblioteca de clases separada. Tengo una cadena de conexión en mi proyecto web (mvc) para que pueda acceder a EF db.

También tengo otro proyecto de prueba unitaria para probar los repositorios. Para que los repositorios accedan a EF db, el archivo app.config del proyecto de prueba tiene la misma cadena de conexión.

Las conexiones DB deben configurarse, no codificarse, en mi opinión.

danludwig
fuente
2
Necesito pasar manualmente la cadena de conexión por código. Estoy usando inyección de dependencia.
Shawn Mclean
1

desde aqui

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

tenga en cuenta que es posible que deba agregar Microsoft.EntityFrameworkCore.SqlServer

Abdullah Tahan
fuente
0

No veo nada malo en su código, uso SqlExpress y funciona bien cuando uso una cadena de conexión en el constructor.

Ha creado una carpeta App_Data en su proyecto, ¿no es así?

Lee Smith
fuente
0

Para cualquiera que haya venido aquí tratando de averiguar cómo configurar la cadena de conexión dinámicamente, y tuvo problemas con las soluciones anteriores (como "El formato de la cadena de inicialización no se ajusta a la especificación que comienza en el índice 0") al configurar la cadena de conexión en el constructor. Así es como solucionarlo:

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
fuente