2012-07-06 35 views
9

Me gustaría proporcionar la cadena de conexión para mi base de datos en tiempo de ejecución. Estoy usando el Entity Framework. Esto es lo que tengo hasta ahoracadena de conexión en tiempo de ejecución de Entity Framework

class MyClassDBContext:DbContext 
{ 
    public MyClassDBContext(string str) : base(str) 
    { 
    this.Database.Connection.ConnectionString = str; 
    } 
} 

Para usar el código anterior, traté

//create connection string 
EntityConnectionStringBuilder myConn = new EntityConnectionStringBuilder(); 
myConn.Provider = "System.Data.SqlClient"; 
myConn.ProviderConnectionString = "user id=xxxx;password=xxxx;server=localhost;database=xxxx;connection timeout=30"; 

//inject the connection string at runtime 
MyClassDBContext a = new MyClassDBContext(myConn.ToString()) 

El código anterior me dio un error diciendo "palabra clave proveedor no compatible". para tratar de depurar este error, he intentado lo siguiente

MyClassDBContext a = new MyClassDBContext("metadata=res://*/Model.csdl|res://*/Model.ssdl|res://*/Model.msl;provider=System.Data.SqlClient;provider connection string=user id=xxxx;password=xxxx;server=localhost;database=xxxx;connection timeout=30") 

Ahora, tengo un error que dice "keyword no compatible". Así que cambié mi código para

MyClassDBContext a = new MyClassDBContext("provider=System.Data.SqlClient;provider connection string=user id=xxxx;password=xxxx;server=localhost;database=xxxx;connection timeout=30") 

Ahora tengo un error que dice "palabra clave proveedor no compatible". Así que de nuevo cambié mi código a

MyClassDBContext a = new MyClassDBContext("user id=xxxx;password=xxxx;server=localhost;database=xxxx;connection timeout=30") 

y ahora funciona !. Mi pregunta es: ¿cómo especifico el proveedor y los metadatos en el tiempo de ejecución? Parece que solo se acepta la cadena de conexión. Estoy usando la Entidad 4.3.1 de Nuget.

Gracias

Respuesta

10

edmx requiere el "Proveedor" y el contenido de "metadatos". EF basada en código primero no requiere esto, requiriendo solo la cadena de conexión normal. Puede usar un SqlConnectionBuilder (en lugar de EntityConnectionStringBuilder) para construir esta cadena de conexión normal si lo desea. Pero como ha visto, solo necesita especificar los detalles de la conexión real. El proveedor y los metadatos no son necesarios en el primer paradigma del Código DbContext de EF 4.3.1.

+1

Entonces, ¿qué haría si tuviera que conectarme a Oracle o MySQL usando el código primero? –

+3

La cadena de conexión EF tiene 'Provider =" System.Data.Entity "' y 'ConnectionString =" res: //big.csdl | res: //ball.ssdl | res: //mud.msl; provider connection string = " ... "'. Las cadenas de conexión normales tienen 'Provider =" System.Data.Client "' (u Oracle o MySql) y 'ConnectionString =" detalles para conectarse a él ''. Estos dos parámetros suelen estar en un app.config o web.config, pero usted elige crearlos de forma dinámica. En EF Code First, tomas el segundo camino. En EDMX land, debe incrustar los detalles de la segunda ruta en la "Ruta de conexión del proveedor" de la primera ruta. Es feo – robrich

7

La clase EntityConnectionStringBuilder se pueden utilizar para especificar proveedor y los metadatos en tiempo de ejecución

por ejemplo

var entityConnectionStringBuilder = new EntityConnectionStringBuilder(); entityConnectionStringBuilder.Provider = "System.Data.SqlClient"; entityConnectionStringBuilder.Metadata = "res: // /Example.csdl|res:// /Example.ssdl|res://*/Example.msl";

favor ver para más información sobre CSDL, SSDL & MSDL en Metadatos EF basado en archivos

+0

sí , eso es lo que intenté y no funcionó. El código me da el error "no se admite la palabra clave del proveedor o palabra clave de metadata no compatible". Consulte la publicación original para obtener más información –

+0

Provider = "System.Data.SqlClient" no debería ser Provider = "System.Data.EntityClient" – HatSoft

+0

Eso puede ser cierto, pero cambiar de proveedor no ayuda ahora porque estoy obteniendo el mismo error al decir que la palabra clave "proveedor" no es compatible. –

4

he seguido este link

y también éste

Modo de empleo EF-Código Primero sin un archivo app.conf?

Básicamente lo que hago es casi como tú, crea un constructor con una cadena y llama a la base.

Pero también configuré el proveedor en este constructor.

aquí hay un ejemplo

public Context(string ConnectionString) : base(ConnectionString) { 
    Database.DefaultConnectionFactory = new SqlCeConnectionFactory("Oracle.DataAccess.Client"); 
} 

esa manera usted puede especificar el proveedor. Y no obtendrá el error de palabra clave de proveedor ya que no necesita especificar en la cadena de conexión

Así es como lo llamo.

var dbCont = new ClassLibrary1.Models.Context("DATA SOURCE=xxx;PASSWORD=xxx;USER ID=xxx"); 

Esperanza que ayuda me llevó mucho tiempo para encontrarlo

7

Sobre la base de HatSoft's answer:

var entityConnectionStringBuilder= new EntityConnectionStringBuilder(); 
entityConnectionStringBuilder.Provider = "System.Data.SqlClient"; 
entityConnectionStringBuilder.ProviderConnectionString = <your SQL Server connection string>; 
entityConnectionStringBuilder.Metadata = "res://*"; 

MyClassDBContext a = new MyClassDBContext(entityConnectionStringBuilder.ToString()); 
+0

hi thx @DavidMcClelland - ¿Esto funcionará para npgsql? – BKSpurgeon

+0

@BKSpurgeon No he tenido que usar esa base de datos aún, déjenos saber lo que averigua :-) –

+0

sí, hay una clase de generador de cadenas, pero me pareció un poco problemático y un poco una pesadilla para el novato - ejecuté con mysql al final. – BKSpurgeon

2

Es vieja pregunta, pero tal vez será útil para alguien

var provider = (DbProviderFactory)System.Data.Entity.DbConfiguration 
      .DependencyResolver 
      .GetService(typeof(DbProviderFactory), "invariant provider name"); 

     var conn = provider.CreateConnection(); 
     //conn.ConnectionString = "sample connection string"; 

     DbInterception.Dispatch.Connection.SetConnectionString(conn, new DbConnectionPropertyInterceptionContext<string>() 
      .WithValue("sample connection string")); 

return new SampleDbContext(conn,true); 
+0

¡Gracias por esta respuesta! El problema al que me enfrentaba era que no estaba usando un CSDL, SSDL o MSDL en mi código, así que no tenía nada para establecer la propiedad Metadata (tampoco pude poner "res: // *"). Al seguir tu sugerencia, pude superar esta limitación. ¡Muy apreciado! –

Cuestiones relacionadas