2010-09-23 12 views
8

Estoy usando Entity Framework 4 en mi proyecto. El Marco ha creado su propia cadena de conexión, por lo que mi web.config connectionStrings archivo de sección examina siguiente:Entity Framework - cadena de conexión redundante

<connectionStrings> 
    <add name="ApplicationServices" connectionString="data source=localhost;user id=user;pwd=pass;initial catalog=VNK" providerName="System.Data.SqlClient" />  
    <add name="VNKEntities" connectionString="metadata=res://*/VNKModel.csdl|res://*/VNKModel.ssdl|res://*/VNKModel.msl;provider=System.Data.SqlClient;provider connection string=&quot;Data Source=localhost;Initial Catalog=VNK;User ID=user;Password=pass;MultipleActiveResultSets=True&quot;" providerName="System.Data.EntityClient" /> 
    </connectionStrings> 

la primera cadena de conexión de llamada ApplicationServices es mi original. El segundo, llamado VNKEntities se ha creado al generar el modelo.

Al revisar el archivo generado * .edmx, he encontrado que este modelo hace referencia a la cadena de conexión, que se muestra a continuación:

/// <summary> 
    /// Initializes a new VNKEntities object using the connection string found in the 'VNKEntities' section of the application configuration file. 
    /// </summary> 
    public VNKEntities() : base("name=VNKEntities", "VNKEntities") 
    { 
     this.ContextOptions.LazyLoadingEnabled = true; 
     OnContextCreated(); 
    } 

Mi pregunta es ¿cómo puedo deshacerse de la VNKEntities cadena de conexión, y dejar solo ApplicationServices, a la que haré referencia desde mi modelo? Me gustaría tener solo una cadena de conexión para la base de datos, porque estoy usando solo una base de datos (reemplazar el parámetro de constructor de name=VNKEntities a name=ApplicationServices no funciona).

Saludos

Respuesta

3

Aunque puede crear la conexión en el código, como se señala @gandjustas (1), no se puede conseguir lejos de tener una cadena de conexión o EntityConnection.

Esto es porque no es realmente redundante. Sí, la parte de conexión de la base de datos es redundante, y @gandjustas le mostró cómo eliminar esa redundancia. Sin embargo, la cadena de conexión del marco de entidad también contiene información sobre su modelo, que no se encuentra en ninguna parte de la cadena de conexión que desea conservar. Esta información modelo tiene que venir de algún lado. Si eliminara la cadena de conexión de la estructura de entidad y usara el constructor de lista de parámetros en ObjectContext, habría eliminado todas las referencias al modelo.

+0

Gracias por la explicación detallada, que me ayudó a entender por qué debería elegir una solución dada por @gandjustas para resolver mi problema. – jwaliszko

1

Tuve el mismo problema. Lo he resuelto de la siguiente manera:

He creado dos archivos edmx, pero al crear el segundo archivo edmx, ignoré la cadena de conexión para guardarla en el archivo de configuración. De esta forma, mi archivo de configuración contendrá solo una cadena de conexión. Luego modifiqué siguientes líneas en mi cadena de conexión:

<add name="MyDbContext" connectionString="metadata=res://*/;provider=System.Data.SqlClient;provider connection string=&quot;data source=abc;initial catalog=mydb;persist security info=True;user id=myuser;password=password;MultipleActiveResultSets=True;App=EntityFramework&quot;" providerName="System.Data.EntityClient" /> 

basta con sustituir "res: //model1.csdl" con "res: // * /" y funciona como un encanto.

Se puede especificar el nombre de la conexión en el constructor de la clase dbcontext como:

public MyDbContext() : base("name=NameOfYourConnectionString") // Name of your connection string 
{ } 

Nota: Estoy utilizando Entity Framework 5.0.

1

Proveeré la implementación completa que hice para resolver este problema (basado en consejos de gandjustas). He escrito un simple envoltorio para el contexto, que puede ser utilizado de la manera siguiente:

using (var wrapper = new ContextWrapper<VNKEntities>()) 
{ 
    // do your stuff based on wrapper.Context 
} 

Tipo ContextWrapper es una plantilla que simplemente se envuelve el contexto que se acaba de construirse en un poco de otra manera (usando sólo una cadena de conexión) y luego expuesto por propiedad. Su implementación interna se coloca a continuación:

public class ContextWrapper<TContext> : IDisposable 
    where TContext : ObjectContext 
{ 
    private TContext _context; 
    private EntityConnectionManager _manager; 
    private bool _disposed; 

    public ContextWrapper() 
     : this(true) 
    { 
    } 

    public ContextWrapper(bool lazyLoadingEnabled) 
    { 
     _disposed = false; 
     _manager = new EntityConnectionManager(); 
     _context = (TContext)Activator.CreateInstance(typeof(TContext), _manager.Connection); 
     _context.ContextOptions.LazyLoadingEnabled = lazyLoadingEnabled; 
    } 

    ~ContextWrapper() 
    { 
     Dispose(false); 
    } 

    public TContext Context 
    { 
     get { return _context; } 
    } 

    public void Dispose() 
    { 
     Dispose(true); 
     GC.SuppressFinalize(this); 

    } 

    protected virtual void Dispose(bool disposing) 
    { 
     if (!_disposed) 
     { 
      if (disposing) 
      { 
       if (_manager != null) 
       { 
        _manager.Dispose(); 
        _manager = null; 
       } 
       var ctx = _context as IDisposable; 
       if (ctx != null) 
       { 
        ctx.Dispose(); 
        _context = null; 
       } 
      } 
     } 
     _disposed = true; 
    } 
} 

Puede ver el uso de la clase personalizada denominada EntityConnectionManager:

internal class EntityConnectionManager : IDisposable 
{ 
    private DbConnection _connection; 
    private EntityConnection _entityConnection; 

    private volatile bool _disposed; 

    public EntityConnectionManager() 
    { 
     var workspace = new MetadataWorkspace(Setting.MetadataWorkspacePaths.Split('|'), new[] { Assembly.ReflectionOnlyLoad(Setting.MetadataAssemblyNameToConsider) }); 

     _connection = new SqlConnection(Setting.ConnectionString); 
     _entityConnection = new EntityConnection(workspace, _connection); 
     _disposed = false; 
    } 

    public EntityConnection Connection 
    { 
     get { return _entityConnection; } 
    } 

    public void Dispose() 
    { 
     Dispose(true); 
     GC.SuppressFinalize(this); 
    } 

    protected virtual void Dispose(bool disposing) 
    { 
     if (!_disposed) 
     { 
      if (disposing) 
      { 
       if (_connection != null) 
       { 
        _connection.Dispose(); 
        _connection = null; 
       } 
       if (_entityConnection != null) 
       { 
        _entityConnection.Dispose(); 
        _entityConnection = null; 
       } 
      } 
     } 
     _disposed = true; 
    } 
} 

Así que ahora usted puede tener la secuencia una conexión:

<connectionStrings> 
    <add name="ApplicationServices" connectionString="data source=localhost;user id=user;pwd=pass;initial catalog=VNK;Pooling=False;MultipleActiveResultSets=True" providerName="System.Data.SqlClient" />  
</connectionStrings> 

y metadatos definido en la sección de configuración de la aplicación (la segunda clave apunta al ensamblaje donde está realmente almacenado su modelo de dominio):

<appSettings> 
    <add key="MetadataWorkspacePaths" value="res://*/VNKModel.csdl|res://*/VNKModel.ssdl|res://*/VNKModel.msl" /> 
    <add key="MetadataAssemblyNameToConsider" value="VNK.Models" /> 
</appSettings> 

La lógica para el tipo Setting es sencilla, ya que simplemente extrae la configuración del archivo de configuración.

Cuestiones relacionadas