ASP.NET Identity:通过 EntityFramework MySQL 提供程序使用 MySQL 存储 (C#)

作者 :Maurycy MarkowskiRaquel Soares De AlmeidaRobert McMurray

本教程介绍如何将 ASP.NET 标识 的默认数据存储机制替换为 EntityFramework (SQL 客户端提供程序) MySQL 提供程序。

本教程将介绍以下主题:

  • 在 Azure 上创建 MySQL 数据库
  • 使用 Visual Studio 2013 MVC 模板创建 MVC 应用程序
  • 配置 EntityFramework 以使用 MySQL 数据库提供程序
  • 运行应用程序以验证结果

在本教程结束时,你将拥有一个 MVC 应用程序,该应用程序包含 ASP.NET 标识存储,该应用程序使用 Azure 中托管的 MySQL 数据库。

在 Azure 上创建 MySQL 数据库实例

  1. 登录到 Azure 门户

  2. 单击页面底部的“ 新建 ”,然后选择“ 应用商店”:

    Azure 门户菜单的屏幕截图,底部突出显示了“应用商店”菜单项,并带有红色矩形。

  3. “选择加载项 ”向导中,选择“ ClearDB MySQL 数据库”,然后单击框架底部的“ 下一步 ”箭头:

    [单击下图将其展开。 ] “选择加载项”向导的屏幕截图,其中突出显示了“清除 D B 我的 SQ L 数据库”,并带有一个红色矩形。

  4. 保留默认 的“免费 ”计划,将 “名称” 更改为 “IdentityMySQLDatabase”,选择离你最近的区域,然后单击框架底部的“ 下一步 ”箭头:

    [单击下图将其展开。 ] “个性化加载项”对话框的屏幕截图,其中显示了“免费计划”选项,以及选中并突出显示了红色矩形的“名称”和“区域”字段。

  5. 单击“ 购买 ”复选标记以完成数据库创建。

    [单击下图将其展开。 ] “查看购买”对话框的屏幕截图,其中突出显示了“购买”按钮,并带有一个红色矩形。

  6. 在创建数据库后,可以从管理门户中的“外接程序”选项卡管理该数据库。 若要检索数据库的连接信息,请单击页面底部的“ 连接信息 ”:

    [单击下图将其展开。 ] 管理门户的屏幕截图,其中突出显示了“添加”选项卡、“标识我的 SQ L 数据库项”和“连接信息”按钮。

  7. 通过单击 CONNECTIONSTRING 字段的复制按钮复制连接字符串并保存;本教程稍后将对 MVC 应用程序使用此信息:

    [单击下图将其展开。 ] “连接信息”对话框的屏幕截图,其中突出显示了“连接字符串”字段右侧的“复制”按钮。

创建 MVC 应用程序项目

若要完成本教程的此部分中的步骤,首先需要安装 Visual Studio Express 2013 for WebVisual Studio 2013。 安装 Visual Studio 后,使用以下步骤创建新的 MVC 应用程序项目:

  1. 打开 Visual Studio 2103。

  2. 单击“开始”页中的“新建项目”,也可以单击“文件”菜单,然后单击“新建项目”:

    [单击下图将其展开。 ] Visual Studio 起始页的屏幕截图,其中突出显示了“新建项目”选项,并带有一个红色矩形。

  3. 显示“ 新建项目 ”对话框时,在模板列表中展开 “Visual C# ”,然后单击“ Web”,然后选择“ ASP.NET Web 应用程序”。 将项目命名为 IdentityMySQLDemo ,然后单击“ 确定”:

    [单击下图将其展开。 ] “新建项目”对话框的屏幕截图,其中左侧展开了 Visual C 哈希标记,并突出显示了 Web。在右侧选择“ASP.NET Web 应用程序”,并在底部的名称字段中选择项目名称“标识我的 S Q L Demo”。

  4. “新建 ASP.NET 项目 ”对话框中,选择具有默认选项的 MVC 模板;这将配置 个人用户帐户 作为身份验证方法。 单击“ 确定”

    [单击下图将其展开。 ] “新建 A S P dot NET 项目”对话框的屏幕截图,其中选择了 M V C 模板并选中了默认选项。

配置 EntityFramework 以使用 MySQL 数据库

更新项目的实体框架程序集

从 Visual Studio 2013 模板创建的 MVC 应用程序包含对 EntityFramework 6.0.0 包的引用,但自该程序集发布以来,已对程序集进行了更新,其中包含显著的性能改进。 若要在应用程序中使用这些最新更新,请执行以下步骤。

  1. 在 Visual Studio 中打开 MVC 项目。

  2. 依次单击“工具”、“NuGet 包管理器”和“包管理器控制台”:

    [单击下图将其展开。 ] Visual Studio 中 M V C 项目的屏幕截图,其中顶部菜单中选择了“工具”,左侧选择了“库包管理器”,右侧选择了“包管理器控制台”。

  3. 包管理器控制台将显示在 Visual Studio 的底部。 键入“Update-Package EntityFramework”,然后按 Enter:

    [单击下图将其展开。 ] Visual Studio 底部的包管理器控制台的屏幕截图,其中命令行上显示了更新包实体框架指令。

为 EntityFramework 安装 MySQL 提供程序

为了使 EntityFramework 连接到 MySQL 数据库,需要安装 MySQL 提供程序。 为此,请打开 包管理器控制台 并键入“Install-Package MySql.Data.Entity -Pre”,然后按 Enter。

注意

这是程序集的预发行版本,因此可能包含 bug。 不应在生产中使用提供程序的预发行版本。

[单击下图将其展开。]

Visual Studio 底部部分中包管理器控制台的屏幕截图,其中命令行上显示了 Install-Package“我的 S q l 点数据点实体虚线 Pre 指令”。

对应用程序的 Web.config 文件进行项目配置更改

在本部分中,将配置实体框架以使用刚安装的 MySQL 提供程序,注册 MySQL 提供程序工厂,并从 Azure 添加连接字符串。

注意

以下示例包含MySql.Data.dll的特定程序集版本。 如果程序集版本发生更改,则需要使用正确的版本修改相应的配置设置。

  1. 在 Visual Studio 2013 中打开项目的 Web.config 文件。

  2. 找到以下配置设置,这些设置定义实体框架的默认数据库提供程序和工厂:

    <entityFramework>
      <defaultConnectionFactory
          type="System.Data.Entity.Infrastructure.LocalDbConnectionFactory, EntityFramework">
        <parameters>
          <parameter value="v11.0" />
        </parameters>
      </defaultConnectionFactory>
      <providers>
        <provider
          invariantName="System.Data.SqlClient"
          type="System.Data.Entity.SqlServer.SqlProviderServices, EntityFramework.SqlServer" />
      </providers>
    </entityFramework>
    
  3. 将这些配置设置替换为以下内容,这将配置实体框架以使用 MySQL 提供程序:

    <entityFramework>
      <providers>
        <provider invariantName="MySql.Data.MySqlClient"
          type="MySql.Data.MySqlClient.MySqlProviderServices, MySql.Data.Entity"/> 
      </providers>
    </entityFramework>
    <system.data>
      <DbProviderFactories>
        <remove invariant="MySql.Data.MySqlClient"></remove>
        <add name="MySQL Data Provider"
          invariant="MySql.Data.MySqlClient"
          description=".Net Framework Data Provider for MySQL"
          type="MySql.Data.MySqlClient.MySqlClientFactory, MySql.Data, Version=6.7.2.0"/>
      </DbProviderFactories>
    </system.data>
    
  4. <找到 connectionStrings> 部分并将其替换为以下代码,该代码将定义托管在 Azure 上的 MySQL 数据库的连接字符串 (请注意,providerName 值也已从原始) 更改:

    <connectionStrings>
      <add name="DefaultConnection"
        providerName="MySql.Data.MySqlClient"
        connectionString="[Insert your ConnectionString from Azure here]"/>
    </connectionStrings>
    

添加自定义 MigrationHistory 上下文

Entity Framework Code First 使用 MigrationHistory 表来跟踪模型更改,并确保数据库架构与概念架构之间的一致性。 但是,默认情况下,此表不适用于 MySQL,因为主键太大。 若要纠正这种情况,需要缩小该表的密钥大小。 为此,请按照以下步骤操作:

  1. 此表的架构信息在 HistoryContext 中捕获,可以将其修改为任何其他 DbContext。 为此,请将名为 MySqlHistoryContext.cs 的新类文件添加到项目中,并将其内容替换为以下代码:

    using System.Data.Common;
    using System.Data.Entity;
    using System.Data.Entity.Migrations.History;
     
    namespace IdentityMySQLDemo
    {
      public class MySqlHistoryContext : HistoryContext
      {
        public MySqlHistoryContext(
          DbConnection existingConnection,
          string defaultSchema)
        : base(existingConnection, defaultSchema)
        {
        }
     
        protected override void OnModelCreating(DbModelBuilder modelBuilder)
        {
          base.OnModelCreating(modelBuilder);
          modelBuilder.Entity<HistoryRow>().Property(h => h.MigrationId).HasMaxLength(100).IsRequired();
          modelBuilder.Entity<HistoryRow>().Property(h => h.ContextKey).HasMaxLength(200).IsRequired();
        }
      }
    }
    
  2. 接下来,需要将 Entity Framework 配置为使用修改后的 HistoryContext,而不是默认的 HistoryContext。 这可以通过利用基于代码的配置功能来完成。 为此,请将名为 MySqlConfiguration.cs 的新类文件添加到项目中,并将其内容替换为:

    using System.Data.Entity;
     
    namespace IdentityMySQLDemo
    {
      public class MySqlConfiguration : DbConfiguration
      {
        public MySqlConfiguration()
        {
          SetHistoryContext(
          "MySql.Data.MySqlClient", (conn, schema) => new MySqlHistoryContext(conn, schema));
        }
      }
    }
    

为 ApplicationDbContext 创建自定义 EntityFramework 初始值设定项

本教程中介绍的 MySQL 提供程序目前不支持实体框架迁移,因此需要使用模型初始值设定项才能连接到数据库。 由于本教程使用 Azure 上的 MySQL 实例,因此需要创建自定义 Entity Framework 初始值设定项。

注意

如果要连接到 Azure 上的 SQL Server 实例,或者使用的是本地托管的数据库,则不需要执行此步骤。

若要为 MySQL 创建自定义实体框架初始值设定项,请使用以下步骤:

  1. 将名为 MySqlInitializer.cs 的新类文件添加到项目,并将其内容替换为以下代码:

    using IdentityMySQLDemo.Models;
    using System.Data.Entity;
    using System.Data.Entity.Infrastructure;
    using System.Linq;
    
    namespace IdentityMySQLDemo
    {
      public class MySqlInitializer : IDatabaseInitializer<ApplicationDbContext>
      {
        public void InitializeDatabase(ApplicationDbContext context)
        {
          if (!context.Database.Exists())
          {
            // if database did not exist before - create it
            context.Database.Create();
          }
          else
          {
            // query to check if MigrationHistory table is present in the database 
            var migrationHistoryTableExists = ((IObjectContextAdapter)context).ObjectContext.ExecuteStoreQuery<int>(
              "SELECT COUNT(*) FROM information_schema.tables WHERE table_schema = 'IdentityMySQLDatabase' AND table_name = '__MigrationHistory'");
    
            // if MigrationHistory table is not there (which is the case first time we run) - create it
            if (migrationHistoryTableExists.FirstOrDefault() == 0)
            {
              context.Database.Delete();
              context.Database.Create();
            }
          }
        }
      }
    }
    
  2. 打开位于 Models 目录中的项目的 IdentityModels.cs 文件,并将其内容替换为以下内容:

    using Microsoft.AspNet.Identity.EntityFramework;
    using System.Data.Entity;
    
    namespace IdentityMySQLDemo.Models
    {
      // You can add profile data for the user by adding more properties to your ApplicationUser
      // class, please visit https://go.microsoft.com/fwlink/?LinkID=317594 to learn more.
      public class ApplicationUser : IdentityUser
      {
      }
    
      public class ApplicationDbContext : IdentityDbContext<ApplicationUser>
      {
        static ApplicationDbContext()
        {
          Database.SetInitializer(new MySqlInitializer());
        }
    
        public ApplicationDbContext()
          : base("DefaultConnection")
        {
        }
      }
    }
    

运行应用程序并验证数据库

完成上述部分中的步骤后,应测试数据库。 为此,请按照以下步骤操作:

  1. Ctrl + F5 生成并运行 Web 应用程序。

  2. 单击页面顶部的“ 注册 ”选项卡:

    [单击下图将其展开。 ] A S P dot NET 网站的屏幕截图,右上角的菜单中突出显示了“注册”选项卡。

  3. 输入新的用户名和密码,然后单击“ 注册”:

    [单击下图将其展开。 ] A S P dot NET 注册对话框的屏幕截图,其中用户名、密码和确认密码字段已完成,下面突出显示了“注册”按钮。

  4. 此时,会在 MySQL 数据库上创建 ASP.NET 标识表,并且用户已注册并登录到应用程序:

    [单击下图将其展开。 ] 用户完成注册后的 S P dot NET 网站的屏幕截图。右上方的菜单中突出显示了带有 Hello 问候语的选项卡,后跟用户名。

安装 MySQL Workbench 工具以验证数据

  1. 从 MySQL 下载页安装 MySQLWorkbench 工具

  2. 在安装向导的“功能选择”选项卡中,选择“应用程序”部分下的“MySQL Workbench”。

  3. 启动应用,并使用在本教程开头创建的 Azure MySQL 数据库中的连接字符串数据添加新连接。

  4. 建立连接后,检查在 IdentityMySQLDatabase 上创建的 ASP.NET 标识表。

  5. 你将看到所有 ASP.NET 标识所需的表都已创建,如下图所示:

    [单击下图将其展开。 ] “我的 S Q L 工作台”工具对话框的屏幕截图。在标识我的 S Q L 数据库上创建的 S P 点 NET 标识表在左下角突出显示。

  6. 例如,检查 aspnetusers 表,以便在注册新用户时为条目检查。

    [单击下图将其展开。 ] s p net users 表的屏幕截图,其中条目显示 ID、用户名、密码哈希、安全标记和鉴别器列。