tiempo framework ejecucion dinamica conexion cambiar cadena c# entity-framework

c# - ejecucion - cambiar cadena de conexion entity framework



Entity Framework de instalación para la cadena de conexión dinámica (3)

Estoy trabajando en una aplicación que utilizará el mismo esquema de base de datos en varias bases de datos. Por esta razón, he creado una base de datos llamada MyTemplate . Cuando se crea un nuevo usuario, tendrán su propia instancia de la base de datos. Por lo tanto, se MyTemplate_[UserName] una base de datos llamada algo así como MyTemplate_[UserName] . Cuando un usuario inicia sesión, debo apuntar sus consultas a su base de datos. Por esta razón, sé que necesito establecer la cadena de conexión en tiempo de ejecución. Mi problema es que también quiero usar Entity Framework.

Actualmente, creé un nuevo .edmx usando MyTemplate como fuente. Pensé que sería capaz de actualizar el código y establecer la cadena de conexión allí. Desafortunadamente, no puedo averiguar cómo configurarlo. El constructor de TemplateEntities no tiene una sobrecarga que me permita pasar una cadena de conexión. Noté que TemplateEntities derivó de DbContext, no creo que este sea el problema.

string connectionString = GetUsersConnectionString(); using (TemplateEntities entities = new TemplateEntities()) { TemplateEntity entity = new TemplateEntity(); // Save to the database entities.TemplateEntity.Add(entity); entities.SaveChanges(); }

¿Estoy creando el .edmx incorrectamente? ¿O me estoy perdiendo algo por completo? Todo lo que busco en Google muestra una sobrecarga que debería permitir pasar una cadena de conexión. Sin embargo, no tengo esa sobrecarga disponible.


Este es el paso a paso que he usado al construir mis soluciones:

  1. En el proyecto que desee, asegúrese de que se instaló Entity Framework usando el menú de opciones "Administrar paquetes Nuget ...".
  2. En el proyecto que desee, haga clic con el botón derecho y luego Agregar-> Nuevo elemento, vaya a Datos y seleccione Modelo de datos de entidad ADO.NET.
  3. Escriba el nombre del modelo, digamos "ExampleModel". Haga clic en Agregar.
  4. Aparecerán cuatro opciones para elegir los contenidos del Modelo, normalmente selecciono la primera para construir el modelo a partir de objetos existentes de la base de datos. Haga clic en Siguiente.
  5. Establece tu conexión de datos. Una vez hecho esto, escriba el nombre de su entidad modelo, digamos "ExampleModelEntities", haga clic en Siguiente.
  6. Seleccione los objetos de la base de datos que estarán presentes en su modelo EF. En el cuadro de entrada del espacio de nombres de modelo, escriba el mismo nombre de modelo del Paso 3 ("Modelo de ejemplo"). Haga clic en Finalizar.

En este punto, se ha creado y agregado un nuevo archivo .edmx al proyecto, que contiene todos sus objetos listos para trabajar. Solo el detalle no deseado es, hasta ahora, la cadena de conexión se ha especificado y guardado en el archivo Web.config de nuestro proyecto.

Para eliminar esto, simplemente vaya al bloque de sección <connectionStrings></connectionStrings> de su Web.config y elimine los detalles desde allí. Ahora trabajaremos para hacer que la cadena de conexión sea legible dinámicamente desde otras fuentes.

Como señaló Nicholas Butler, lo siguiente será crear una "versión" de la clase de entidad parcial original creada (ExampleModelEntities), que nos permitirá pasar la cadena de conexión dinámica. Esto es posible ya que la clase de entidad original creada hereda de DBContext, que es la que contiene el constructor para pasar dicha conexión.

Para hacer lo anterior, agregue una nueva clase vacía a su proyecto. Asegúrese de escribir el mismo nombre proporcionado en el Paso 5, siguiendo nuestro estudio de caso "ExampleModelEntities". Debajo del código a implementar:

DO#

public partial class ExampleModelEntities { public ExampleModelEntities(string connString) : base(connString) { } }

VB.Net:

Partial Public Class ExampleModelEntities Public Sub New(ByVal connString As String) MyBase.New(connString) End Sub End Class

En este momento, su código está listo para trabajar con cadenas de conexión dinámicas provenientes de otras fuentes. Una de estas fuentes podría ser pasar una cadena de conexión proveniente de otro campo almacenado en una base de datos diferente o usar la clase EntityConnectionStringBuilder .

El siguiente ejemplo se implementa en VB.Net, pero use alguna herramienta como Telerik para traducir. Digamos que estamos obteniendo una lista de objetos de una determinada base de datos, solo queremos pasar dinámicamente la cadena de conexión proveniente de otro campo almacenado en una base de datos diferente. Para lograr esto, el código se vería como sigue:

Public Shared Function Get_List(ByVal Param1 As String) As List(Of Stored_Procedure_Code_Result) Try Dim Object_List_Result As List(Of Stored_Procedure_Code_Result) = Nothing Using dbContext As New ExampleModelEntities(Configuration.CONNECTION_STRING) Object_List_Result = dbContext.Stored_Procedure_Code(Param1).ToList dbContext.Dispose() End Using Return Object_List_Result Catch ex As Exception Throw ex End Try End Function

Donde Configuration.CONNECTION_STRING es el valor de la cadena de conexión dinámica, expresado mediante un Módulo llamado "Configuración" y una función que recupera dicho valor.

Para evitar inexactitudes de formato, el valor debe almacenarse utilizando el siguiente formato:

Para la autenticación de Windows usando Entity Framework:

UPDATE [DBConnections].[dbo].[ListOfConnectionsTable] SET ConnValue = ''metadata=res://*/ExampleModel.csdl|res://*/ExampleModel.ssdl|res://*/ExampleModel.msl;provider=System.Data.SqlClient;provider connection string="Data Source=ServerName;Initial Catalog=DBName;Integrated Security=True"''

Para la autenticación SQL utilizando Entity Framework:

UPDATE [DBConnections].[dbo].[ListOfConnectionsTable] SET ConnValue = ''metadata=res://*/ExampleModel.csdl|res://*/ExampleModel.ssdl|res://*/ExampleModel.msl;provider=System.Data.SqlClient;provider connection string="Persist Security Info=False;User ID=XXXXXX;Password=XXXXXXX;Initial Catalog=DBName;Data Source=ServerName;App=YourAppName;Network Library=dbmssocn"''

Finalmente, extendiendo la respuesta proporcionada por Mark, en Microsoft hay una explicación detallada sobre cómo trabajar con la clase EntityConnectionStringBuilder, que también se puede usar para crear cadenas de conexión dinámicas y luego pasar este valor a pedido.


La clase TemplateEntities generada se marca como partial .

Todo lo que tiene que hacer es agregar otro archivo con otra parte de la definición de clase parcial que expone el constructor que desea usar:

partial class TemplateEntities { public TemplateEntities( string nameOrConnectionString ) : base( nameOrConnectionString ) { } }

Luego pasa tu cadena de conexión a este constructor.

Desea colocar este código en un archivo diferente para que no se sobrescriba al actualizar su modelo edmx.


La respuesta de Nicholas Butler es bastante correcta. Además de lo que dijo, me enfrenté con el problema de tomar una cadena de conexión existente para el marco de la entidad y simplemente apuntarla a una base de datos diferente que tenía la misma estructura. Usé el siguiente código para cambiar solo la fuente de datos de la cadena existente:

var originalConnectionString = System.Configuration.ConfigurationManager.ConnectionStrings["CSName"].ConnectionString; var ecsBuilder = new EntityConnectionStringBuilder(originalConnectionString); var sqlCsBuilder = new SqlConnectionStringBuilder(ecsBuilder.ProviderConnectionString) { DataSource = "newDBHost" }; var providerConnectionString = sqlCsBuilder.ToString(); ecsBuilder.ProviderConnectionString = providerConnectionString; string contextConnectionString = ecsBuilder.ToString(); using (var db = new SMSContext(contextConnectionString)) { ... }