当前位置: 首页 > 面试题库 >

实体框架6的动态MySQL数据库连接

汪阳飇
2023-03-14
问题内容

我希望将动态连接字符串传递给实体框架上下文。我有150多个相同的模式(每个帐户一个),我想这样选择连接:

ApplicationDbContext db = new ApplicationDbContext("dbName");

从理论上讲,这很容易,因为我可以创建一个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);
}

仅传递连接字符串名称时,我可以成功连接,但如下所示动态生成时,则不能成功。我现在意识到这是因为web.config中的连接字符串具有providerName="MySql.Data.MySqlClient"属性。

但是,当我将实际的连接字符串动态传递给该连接时,它假定它需要连接到SQL Server而不是MySQL,并且由于连接字符串无效而失败。

问题是,如果动态创建提供程序名称,该如何将其传递给连接字符串?


问题答案:

Entity Framework 6提供了一些方便的细微更改,这些更改有助于使MySQL正常工作并创建动态数据库连接。

使MySQL与Entity Framework 6配合使用

首先,在我回答这个问题之日,与EF6兼容的唯一.Net连接器驱动程序是MySQL .Net Connectior
6.8.1(Beta开发版本),可以在此处访问官方MySQL网站

安装后,请从Visual Studio解决方案中引用以下文件:

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

您还需要将这些文件复制到在构建期间项目可以访问的位置,例如bin目录。

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

连接字符串:

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

还可以在<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>

如果从默认的sql服务器连接更改defaultConnectionFactory,请不要忘记删除<parameter>嵌套在defaultConnectionFactory节点中的节点。MysqlConnectionFactory的构造函数不接受任何参数,如果参数仍然存在,它将失败。

在这个阶段,使用Entity连接到MySQL非常容易,您可以按名称引用上面的connectionString。请注意,如果按名称连接,即使该defaultConnectionFactory节点仍然指向SQL
Server(默认情况下也是如此),此操作也将起作用。

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

这只是正常连接的问题:

ApplicationDbContext db = ApplicationDbContext();

连接到动态选择的数据库名称

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

重要的提示

如果还没有,如果希望动态连接到MySQL,则必须在Web.config中更改defaultConnectionFactory。由于我们将直接将连接字符串传递给上下文构造函数,因此除非在web.config中指定,否则它将不知道要使用哪个提供程序,并将转向其默认连接工厂。请参阅上面的操作方法。

您可以像这样手动将连接字符串传递给上下文:

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

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

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

现在,我们可以构建一个辅助方法并更改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");
    }
}

现在,您的代码优先迁移和种子方法将针对developmentdbMySQL数据库中的架构

希望这可以帮助某人:)



 类似资料:
  • 我曾想过简单地对数据库运行一个小命令并捕获任何异常,然而,如果出现问题(例如app.config丢失或数据库服务器关闭),应用程序将花费大量时间运行此代码,然后抛出异常(大约1分钟)。我想这是由于连接超时等,但我已经摆弄了这样的属性没有任何作用。 有没有人能提供任何关于去哪里的建议?

  • 场景: 我有两个MySQL数据库: 大型主数据库 小型客户端数据库 示例表: 大数据库用户: 文本用户名 int id varchar登录 varchar密码 ...更多的领域 客户端数据库用户 内部id int UNIQUE api\u id(来自master的id) varchar登录 varchar密码 问题:我需要同步数据库,但我不知道如何以最佳方式进行同步。我读过这个问题,但它很老了,没

  • 问题内容: 我正在尝试执行本教程http://www.asp.net/mvc/tutorials/getting-started-with-aspnet- mvc3/getting-started-with- mvc3-part4-cs, 但不是使用精简版的SQL Server我在本地计算机上使用完整安装。我阅读本教程的方式是,实体框架是根据我定义的对象创建表的。我的问题是,在运行项目时,我总是得

  • 这是我的代码: 但是当我从控制器调用函数时。它显示错误 在上一个异步操作完成之前,在此上下文上启动了第二个操作。使用“await”确保在该上下文上调用另一个方法之前已完成任何异步操作。任何实例成员都不能保证线程安全。 请帮我解决这个问题。

  • 我有一个带有“Status”布尔值的付款模型,该布尔值默认为false。付款后,我需要将特定付款的“状态”更新为true。 这是我一直试图用来更改特定数据库条目的代码,但它并没有改变它。我做错了什么? 谢谢 这就是最终起作用的原因:

  • 问题内容: 我正在Laravel 5(.1)中创建一个应用程序,在该应用程序中需要连接到不同的数据库。唯一的问题是,它不知道必须连接到哪个数据库,因此无法在config中使用database.php。控制器负责使用动态给定的连接详细信息进行连接。 如何建立与数据库的新连接,包括使用DB类?(或者这可能) 提前致谢! 问题答案: 最简单的解决方案是在运行时设置数据库配置。Laravel可能希望从文件