ASP.NET Identity:通过 EntityFramework MySQL 提供程序使用 MySQL 存储 (C#)
作者 :Maurycy Markowski、 Raquel Soares De Almeida、 Robert McMurray
本教程介绍如何将 ASP.NET 标识 的默认数据存储机制替换为 EntityFramework (SQL 客户端提供程序) MySQL 提供程序。
本教程将介绍以下主题:
- 在 Azure 上创建 MySQL 数据库
- 使用 Visual Studio 2013 MVC 模板创建 MVC 应用程序
- 配置 EntityFramework 以使用 MySQL 数据库提供程序
- 运行应用程序以验证结果
在本教程结束时,你将拥有一个 MVC 应用程序,该应用程序包含 ASP.NET 标识存储,该应用程序使用 Azure 中托管的 MySQL 数据库。
在 Azure 上创建 MySQL 数据库实例
登录到 Azure 门户。
单击页面底部的“ 新建 ”,然后选择“ 应用商店”:
在 “选择加载项 ”向导中,选择“ ClearDB MySQL 数据库”,然后单击框架底部的“ 下一步 ”箭头:
保留默认 的“免费 ”计划,将 “名称” 更改为 “IdentityMySQLDatabase”,选择离你最近的区域,然后单击框架底部的“ 下一步 ”箭头:
单击“ 购买 ”复选标记以完成数据库创建。
在创建数据库后,可以从管理门户中的“外接程序”选项卡管理该数据库。 若要检索数据库的连接信息,请单击页面底部的“ 连接信息 ”:
通过单击 CONNECTIONSTRING 字段的复制按钮复制连接字符串并保存;本教程稍后将对 MVC 应用程序使用此信息:
创建 MVC 应用程序项目
若要完成本教程的此部分中的步骤,首先需要安装 Visual Studio Express 2013 for Web 或 Visual Studio 2013。 安装 Visual Studio 后,使用以下步骤创建新的 MVC 应用程序项目:
打开 Visual Studio 2103。
单击“开始”页中的“新建项目”,也可以单击“文件”菜单,然后单击“新建项目”:
显示“ 新建项目 ”对话框时,在模板列表中展开 “Visual C# ”,然后单击“ Web”,然后选择“ ASP.NET Web 应用程序”。 将项目命名为 IdentityMySQLDemo ,然后单击“ 确定”:
在 “新建 ASP.NET 项目 ”对话框中,选择具有默认选项的 MVC 模板;这将配置 个人用户帐户 作为身份验证方法。 单击“ 确定”:
配置 EntityFramework 以使用 MySQL 数据库
更新项目的实体框架程序集
从 Visual Studio 2013 模板创建的 MVC 应用程序包含对 EntityFramework 6.0.0 包的引用,但自该程序集发布以来,已对程序集进行了更新,其中包含显著的性能改进。 若要在应用程序中使用这些最新更新,请执行以下步骤。
在 Visual Studio 中打开 MVC 项目。
依次单击“工具”、“NuGet 包管理器”和“包管理器控制台”:
包管理器控制台将显示在 Visual Studio 的底部。 键入“Update-Package EntityFramework”,然后按 Enter:
为 EntityFramework 安装 MySQL 提供程序
为了使 EntityFramework 连接到 MySQL 数据库,需要安装 MySQL 提供程序。 为此,请打开 包管理器控制台 并键入“Install-Package MySql.Data.Entity -Pre”,然后按 Enter。
注意
这是程序集的预发行版本,因此可能包含 bug。 不应在生产中使用提供程序的预发行版本。
[单击下图将其展开。]
对应用程序的 Web.config 文件进行项目配置更改
在本部分中,将配置实体框架以使用刚安装的 MySQL 提供程序,注册 MySQL 提供程序工厂,并从 Azure 添加连接字符串。
注意
以下示例包含MySql.Data.dll的特定程序集版本。 如果程序集版本发生更改,则需要使用正确的版本修改相应的配置设置。
在 Visual Studio 2013 中打开项目的 Web.config 文件。
找到以下配置设置,这些设置定义实体框架的默认数据库提供程序和工厂:
<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>
将这些配置设置替换为以下内容,这将配置实体框架以使用 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>
<找到 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,因为主键太大。 若要纠正这种情况,需要缩小该表的密钥大小。 为此,请按照以下步骤操作:
此表的架构信息在 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(); } } }
接下来,需要将 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 创建自定义实体框架初始值设定项,请使用以下步骤:
将名为 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(); } } } } }
打开位于 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") { } } }
运行应用程序并验证数据库
完成上述部分中的步骤后,应测试数据库。 为此,请按照以下步骤操作:
按 Ctrl + F5 生成并运行 Web 应用程序。
单击页面顶部的“ 注册 ”选项卡:
输入新的用户名和密码,然后单击“ 注册”:
此时,会在 MySQL 数据库上创建 ASP.NET 标识表,并且用户已注册并登录到应用程序:
安装 MySQL Workbench 工具以验证数据
从 MySQL 下载页安装 MySQLWorkbench 工具
在安装向导的“功能选择”选项卡中,选择“应用程序”部分下的“MySQL Workbench”。
启动应用,并使用在本教程开头创建的 Azure MySQL 数据库中的连接字符串数据添加新连接。
建立连接后,检查在 IdentityMySQLDatabase 上创建的 ASP.NET 标识表。
你将看到所有 ASP.NET 标识所需的表都已创建,如下图所示:
例如,检查 aspnetusers 表,以便在注册新用户时为条目检查。