fra*_*ler 22 c# mysql asp.net entity-framework entity-framework-6
我希望将动态连接字符串传递给实体框架上下文.我有超过150个相同的模式(每个帐户一个),我想选择这样的连接:
ApplicationDbContext db = new ApplicationDbContext("dbName");
Run Code Online (Sandbox Code Playgroud)
理论上这很容易,因为我可以创建一个connectionString并将其作为构造函数的参数传递,例如:
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);
}
Run Code Online (Sandbox Code Playgroud)
我只是传递连接字符串名称时可以成功连接,但是当我动态生成它时不能如下所示.我现在意识到这是因为web.config中的连接字符串中包含providerName="MySql.Data.MySqlClient"属性.
当我将实际连接字符串动态传递给连接时,它假定它需要连接到SQL Server而不是MySQL,并且由于连接字符串无效而失败.
问题是,如果我动态创建提供者名称,如何将提供者名称传递给连接字符串?
fra*_*ler 54
实体框架6提供了一些方便的细微更改,有助于MySQL工作和创建动态数据库连接.
首先,在我回答这个问题的日期,与EF6兼容的唯一.Net连接器驱动程序是MySQL .Net Connectior 6.8.1(Beta开发版),可在MySQL官方网站上找到.
安装后,从Visual Studio解决方案中引用以下文件:
您还需要将这些文件复制到构建期间项目可访问的位置,例如bin目录.
接下来,您需要向Web.config(或基于桌面的App.config)文件添加一些项目.
连接字符串:
<connectionStrings>
<add name="mysqlCon"
connectionString="Server=localhost;Database=dbName;Uid=username;Pwd=password"
providerName="MySql.Data.MySqlClient" />
</connectionStrings>
Run Code Online (Sandbox Code Playgroud)
还可以在<entityFramework />和<providers />节点内添加提供程序(在处理动态定义的数据库时,这是我答案的第二部分中绝对必须的),您可以更改<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>
Run Code Online (Sandbox Code Playgroud)
如果从默认的sql server连接更改defaultConnectionFactory,请不要忘记删除<parameter>嵌套在defaultConnectionFactory节点中的节点.MysqlConnectionFactory不为其构造函数采用任何参数,如果参数仍然存在则会失败.
在这个阶段,使用Entity连接到MySQL很容易,您可以通过名称引用上面的connectionString.请注意,如果按名称连接,即使defaultConnectionFactory节点仍指向SQL Server(默认情况下也是如此),这将起作用.
public class ApplicationDbContext: DbContext
{
public ApplicationDbContext() : base("mysqlCon")
{
}
}
Run Code Online (Sandbox Code Playgroud)
这只是正常连接的问题:
ApplicationDbContext db = ApplicationDbContext();
Run Code Online (Sandbox Code Playgroud)
此时,您可以轻松连接到我们可以作为参数传递的数据库,但我们需要做一些事情.
如果您还没有,如果您希望动态连接到MySQL,则必须更改Web.config中的defaultConnectionFactory.由于我们将连接字符串直接传递给上下文构造函数,因此除非在web.config中指定,否则它将不知道要使用哪个提供程序并将转向其默认连接工厂.请参阅上文,了解如何执行此操作.
您可以手动将连接字符串传递给上下文,如下所示:
public ApplicationDbContext() : base("Server:localhost;...")
{
}
Run Code Online (Sandbox Code Playgroud)
但为了使它更容易一些,我们可以在设置mySQL时对上面建立的连接字符串进行一些小改动.只需添加一个占位符,如下所示:
<add name="mysqlCon" connectionString="Server=localhost;Database={0};Uid=username;Pwd=password" providerName="MySql.Data.MySqlClient" />
Run Code Online (Sandbox Code Playgroud)
现在我们可以构建一个帮助器方法并更改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);
}
}
Run Code Online (Sandbox Code Playgroud)
如果您正在使用迁移,您会发现ApplicationDbContext将由框架传递给您的Seed方法,它将失败,因为它不会传入我们为数据库名称输入的参数.
将以下类添加到上下文类的底部(或任何地方)以解决该问题.
public class MigrationsContextFactory : IDbContextFactory<ApplicationDbContext>
{
public ApplicationDbContext Create()
{
return new ApplicationDbContext("developmentdb");
}
}
Run Code Online (Sandbox Code Playgroud)
您的代码优先迁移和种子方法现在将以developmentdbMySQL数据库中的架构为目标.
希望这有助于某人:)