domingo, 12 de febrero de 2012

Generar una cadena de conexión para Entity Framework

Cómo sabrás, un modelo de Entity Framework utiliza una conexión del tipo EntityConnection que a su vez utiliza una conexión específica de un Data Provider como puede ser SqlConnection.

La cadena de conexión de EntityConnection puede resultar un tanto especial si estamos acostumbrados a las cadenas de conexión de toda la vida. En cualquier caso, una cadena de conexión es agregada a nuestro fichero App.config o web.config automáticamente cuando agregamos el modelo a nuestro proyecto.

Un ejemplo de cadena de conexión sería el siguiente:

<add name="PedidosEntities" connectionString="metadata=res://*/Pedidos.csdl|res://*/Pedidos.ssdl|res://*/Pedidos.msl;provider=System.Data.SqlClient;provider connection string=&quot;data source=(local);initial catalog=EF;persist security info=True;user id=sa;password=******;multipleactiveresultsets=True;App=EntityFramework&quot;" providerName="System.Data.EntityClient" />

Como puedes comprobar, una cadena de conexión de EntityConnection se puede dividir en 3 partes principales:



  • metadata. Ruta a los metadatos del modelo EDM (esto es la información ssdl, csdl y msl del modelo)

  • provider. Nombre de un proveedor de datos específico (esto es el nombre del proveedor que utilizaremos para conectarnos a la base de datos)

  • provider connection string. Cadena de conexión específica del proveedor de datos anteriormente señalado.

Si tienes que generar esta cadena de conexión en tiempo de ejecución porque quieres conectarte a un origen de datos distinto o por cualquier otro motivo, lo más sensato es hacer uso de los builders oportunos que nos ayudarán en el proceso.


Como referencia he tomado el código expuesto en este blog http://blogs.msdn.com/b/rickandy/archive/2008/12/09/explicit-connection-string-for-ef.aspx, pero lo he modificado para mis cubrir mis propias necesidades:

Imports System.Data.SqlClient
Imports System.Data.EntityClient
Public Class EFUtils
    Public Shared Function GetEntityConnectionString( _
        ByVal dataSource As String, _
        ByVal initialCatalog As String, _
        ByVal userId As String, _
        ByVal password As String, _
        ByVal applicationName As String, _
        ByVal edmFileName As String) As String
        Dim providerName As String = "System.Data.SqlClient"
        Dim sqlConnectionStringBuilder As New SqlConnectionStringBuilder()
        sqlConnectionStringBuilder.DataSource = dataSource
        sqlConnectionStringBuilder.InitialCatalog = initialCatalog
        sqlConnectionStringBuilder.UserID = userId
        sqlConnectionStringBuilder.Password = password
        sqlConnectionStringBuilder.ApplicationName = applicationName
        sqlConnectionStringBuilder.MultipleActiveResultSets = True
        Dim providerString As String = sqlConnectionStringBuilder.ToString()
        Dim entityConnectionStringBuilder As New EntityConnectionStringBuilder()
        entityConnectionStringBuilder.Provider = providerName
        entityConnectionStringBuilder.ProviderConnectionString = providerString
        If String.IsNullOrEmpty(edmFileName) Then
            entityConnectionStringBuilder.Metadata = "res://*"
        Else
            entityConnectionStringBuilder.Metadata = String.Format(".\{0}.csdl|.\{0}.ssdl|.\{0}.msl", edmFileName)
        End If
        Return entityConnectionStringBuilder.ToString()
    End Function
End Class

Lo más relevante de este código es que utilizaremos el parámetro edmFileName para saber si la la cadena de conexión de EntityConnection asume que los metadatos están disponibles como recursos incrustados en el ensamblado (opción por defecto) o para saber si se ha seleccionado la opción “Copiar en el directorio de salida”


Ahora simplemente utilizaremos nuestra nueva cadena de conexión con el constructor de nuestro contexto de trabajo, que acepta una cadena de conexión:

Dim connectionString = EFUtils.GetEntityConnectionString( _
    "lobezno", "Pedidos", "sa", "******", "ConsoleApplication1", String.Empty)
Using conn As New EntityClient.EntityConnection(connectionString)
End Using
Using ctx As New PedidosEntities(connectionString)
End Using

Un saludo!

3 comentarios:

  1. y si en vez de recuperar, se desea setear los valores de la cadena?, como user y pass ?

    ResponderEliminar
  2. Hola:

    En el siguiente código:

    Using ctx As New PedidosEntities(connectionString)
    End Using

    Me dice que tiene demasiados paramentros, por lo que no reconoce el constructor con connectionString.

    ¿Como lo puedo Solucionar?

    ResponderEliminar
  3. Public Function GetEntityConnectionString() As String
    Dim edmFileName As String = nombreDelModelo.edmx
    Dim providerName As String = "System.Data.SqlClient"
    Dim sqlConnectionStringBuilder As New SqlConnectionStringBuilder()
    sqlConnectionStringBuilder.DataSource = mdlPublicVars.servidor
    sqlConnectionStringBuilder.InitialCatalog = mdlPublicVars.bd
    sqlConnectionStringBuilder.UserID = usuarioSistema
    sqlConnectionStringBuilder.Password = claveSistemas
    sqlConnectionStringBuilder.ApplicationName = "EntityFramework"
    sqlConnectionStringBuilder.MultipleActiveResultSets = True
    Dim providerString As String = sqlConnectionStringBuilder.ToString()
    Dim entityConnectionStringBuilder As New EntityConnectionStringBuilder()
    entityConnectionStringBuilder.Provider = providerName
    entityConnectionStringBuilder.ProviderConnectionString = providerString
    entityConnectionStringBuilder.Metadata = "res://*/miModelo.csdl|res://*/miModelo.ssdl|res://*/miModelo.msl"
    Return entityConnectionStringBuilder.ToString()
    End Function

    ResponderEliminar