简体   繁体   中英

EntityFramwork, using multiple databases/connections

I have the following Problem. I'm using Entity Framework 6 and i want to be able to change the used database on runtime or atleast I want to be able to check connection information when entered in the Options. My problem is that we want to support MySql and LocalDB v12.0 so simple exchanging the connections string doesn't help here - I have to exchange the ExecutionStrategy and the ConnectionFactory.

EF seems to lock down all configurations so I'm not able to change it on runtime, is there a workarround for this? For the moment I've tried to create several DbConfigurations and derive a context for each configuration with a definition of [DbConfigurationType(typeof(LocalDbConfigruation))] .

I expected this to fail, but i thougt it would be worth a try ;)

Maybe there is someone out there who can help me with some tipps and tricks.

There is another option that utilizes a base context. In the below example I am using MSSQL connection and Oracle connection. You can extend the base context for however many database connection types you wish. This method opens a ton of other great possibilities, but it should also work for your situation.

BaseContext.cs

using System.Data.Entity;

namespace MultipleConnections.Models
{
    public class BaseContext<TContext> : DbContext where TContext : DbContext
    {
        static BaseContext()
        {
            Database.SetInitializer<TContext>(null);
        }

        public BaseContext(string connectionString = "Name=MSSQLEntities")
            : base(connectionString)
        {}
    }
}

MSSQLModel.cs

using System.Data.Entity;

namespace MultipleConnections.Models
{
    // Extending Base Context will use default MSSQLEntities connection
    public class MSSQLContext : BaseContext<MSSQLContext>
    {
       ...apply DbSet<> and other loveliness...           
    }
}

OracleModel.cs

using System.Data.Entity;

namespace MultipleConnections.Models
{
    // Extending Base Context
    public class OracleContext : BaseContext<OracleContext>
    {
        // Declare Oracle connection in Constructor to override default
        // MSSQL connection
        public OracleContext()
            : base("Name=OracleEntities")
        { }
       ...apply DbSet<> and other loveliness...           
    }
}

Ok, problem seems to be solved now. I'm working with DbConnections now.

public MyContext() : base(ConnectionManager.Connection, true)
{
    Database.SetInitializer<MyContext>(new MyContextInitializer());
    Configuration.ProxyCreationEnabled = false;
}

public MyContext(DbConnection connection) : base(connection, true)
{
    Database.SetInitializer<MyContext>(new MyContextInitializer());
    Configuration.ProxyCreationEnabled = false;
}

I create the DbConnection in a special class, I think it would not be appropriate to post the code here. But it basically does something like this:

DbConnection conn = null;

switch (Type)
{
   case ConnectionType.LocalDB:
      conn = DbProviderFactories.GetFactory("System.Data.SqlClient").CreateConnection();
      break;
   case ConnectionType.MySql:
      conn = DbProviderFactories.GetFactory("MySql.Data.MySqlClient").CreateConnection();
      break;
   default:
      throw new System.InvalidOperationException();
}

conn.ConnectionString = "Add provider specific connection string here";

Then you just have to give the code somhow to the context. In my case I have a ConnectionManager from where I read the "defaul connection" when i call MyContext() and there is a second Ctor which i call for "test connections".

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM