dynamicMySQL数据库连接entity framework6

我希望将dynamic连接string传递给entity framework上下文。 我有超过150模式是相同的(每个帐户一个),我想select连接如下:

ApplicationDbContext db = new ApplicationDbContext("dbName"); 

从理论上讲,这将是相当容易的,因为我可以创build一个connectionString并将其作为构造函数的parameter passing,例如:

 public ApplicationDbContext(string dbName) : base(GetConnectionString(dbName)) { } public static string GetConnectionString(string dbName) { // The connectionString passed is something like: // Server=localhost;Database={0};Uid=username;Pwd=password var connString = ConfigurationManager .ConnectionStrings["MyDatabase"] .ConnectionString .ToString(); return String.Format(connString, dbName); } 

当我只传递连接string名称时,我可以连接成功,但不能当我如下dynamic生成它。 我现在意识到,这是因为web.config中的连接string中有providerName="MySql.Data.MySqlClient"属性。

当我将实际连接stringdynamic传递给连接时,它假定它需要连接到SQL Server而不是MySQL,并且由于连接string无效而失败。

问题是,如果我dynamic创build它,我如何将提供程序名称传递给连接string?

entity framework6提供了一些方便的细微变化,这有助于获得MySQL的工作,并创builddynamic数据库连接。

让MySQL使用entity framework6

首先,在回答这个问题时,与EF6兼容的唯一.Net连接器驱动程序是MySQL .Net Connectior 6.8.1(Beta开发版本),可以在这里的官方MySQL网站上find 。

安装完成后,从Visual Studio解决scheme中引用以下文件:

  • Mysql.Data.dll
  • Mysql.Data.Entity.EF6.dll

您还需要将这些文件复制到构build时可以访问项目的某处,如bin目录。

接下来,您需要添加一些项目到您的Web.config(或App.config,如果在基于桌面的)文件。

连接string:

 <connectionStrings> <add name="mysqlCon" connectionString="Server=localhost;Database=dbName;Uid=username;Pwd=password" providerName="MySql.Data.MySqlClient" /> </connectionStrings> 

还可以在<entityFramework /><providers />节点内添加提供程序(在处理dynamic定义的数据库时,这是绝对必须在我的答案的第二部分),您可以更改<defaultConnectionFactory />节点:

 <entityFramework> <defaultConnectionFactory type="MySql.Data.Entity.MySqlConnectionFactory, MySql.Data.Entity.EF6" /> <providers> <provider invariantName="MySql.Data.MySqlClient" type="MySql.Data.MySqlClient.MySqlProviderServices, MySql.Data.Entity.EF6" /> </providers> </entityFramework> 

如果您从默认的sql server连接中更改defaultConnectionFactory,请不要忘记删除嵌套在defaultConnectionFactory节点中的<parameter>节点。 MysqlConnectionFactory不会为其构造函数使用任何参数,如果参数仍然存在,将会失败。

在这个阶段,用实体连接到MySQL是很容易的,你可以通过名字来引用上面的connectionString。 请注意,如果通过名称进行连接,即使defaultConnectionFactory节点仍指向SQL Server(默认情况下也是如此),这将工作。

 public class ApplicationDbContext: DbContext { public ApplicationDbContext() : base("mysqlCon") { } } 

这只是一个正常连接的问题:

 ApplicationDbContext db = ApplicationDbContext(); 

连接到dynamicselect的数据库名称

在这一点上,很容易连接到一个我们可以作为parameter passing的数据库,但是我们需要做一些事情。

重要的提示

如果你还没有,如果你想dynamic连接到MySQL,你必须改变Web.config中的defaultConnectionFactory。 由于我们将连接string直接传递给上下文构造函数,因此它将不知道使用哪个提供程序,并将转到其默认连接工厂,除非在web.config中指定。 见上面如何做到这一点。

你可以像这样手动传递一个连接string到上下文:

 public ApplicationDbContext() : base("Server:localhost;...") { } 

但为了使它更容易一点,我们可以对设置mySQL时我们上面所做的连接string进行一些小改动。 只需添加一个占位符,如下所示:

 <add name="mysqlCon" connectionString="Server=localhost;Database={0};Uid=username;Pwd=password" providerName="MySql.Data.MySqlClient" /> 

现在我们可以构build一个帮助器方法,并更改ApplicationDbContext类,如下所示:

 public class ApplicationDbContext: DbContext { public ApplicationDbContext(string dbName) : base(GetConnectionString(dbName)) { } public static string GetConnectionString(string dbName) { // Server=localhost;Database={0};Uid=username;Pwd=password var connString = ConfigurationManager.ConnectionStrings["mysqlCon"].ConnectionString.ToString(); return String.Format(connString, dbName); } } 

如果您正在使用数据库迁移,则以下步骤很重要

如果你正在使用迁移,你会发现ApplicationDbContext将被框架传递给你的Seed方法,并且会失败,因为它不会传入我们为数据库名放入的参数。

将下面的类添加到上下文类的底部(或者任何地方)以解决这个问题。

 public class MigrationsContextFactory : IDbContextFactory<ApplicationDbContext> { public ApplicationDbContext Create() { return new ApplicationDbContext("developmentdb"); } } 

您的代码优先迁移和种子方法现在将针对MySQL数据库中的developmentdb模式。

希望这可以帮助别人:)