Core Identity 迁移数据 - Core 基础教程 - 简单教程,简单编程
原文: Core Identity 迁移数据 - Core 基础教程 - 简单教程,简单编程
Core Identity 迁移数据
上一章节中我们配置了 Identity ,也让我们的应用程序正常运行起来了,在访问未授权页面的时候会跳转到/Accout/Login
页面。接下来我们就要实现登录的功能
但是,咦,好像还没创建用户表呢..哎呀,不是没创建用户表,而是没做 Identity 的数据迁移
那么,本章节接下来的内容,就开始迁移 Identity 数据呗
数据库连接配置
对了,我在看官方文档的过程中,发现了两种配置数据库连接的方法
一、第一种是在Startup
类中的ConfigureServices
方法中配置
services.AddEntityFrameworkSqlite().AddDbContext<HelloWorldDBContext>(options => options.UseSqlite(Configuration["database:connection"]));
这种方法需要我们的HelloWorldDBContext
有一个可以接受DbContextOptions<HelloWorldDBContext>
类型参数的构造函数
public HelloWorldDBContext(DbContextOptions<HelloWorldDBContext> options): base(options){ }
二、第二种方法只需要在HelloWorldDBContext
类中重写方法OnConfiguring
protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder) { optionsBuilder.UseSqlite("Data Source=blogging.db"); }
然后在Startup
类中的ConfigureServices
方法种就可以这么写了
services.AddEntityFrameworkSqlite().AddDbContext<HelloWorldDBContext>();
看起来是不是第二种更简单更方便更简洁
后知后觉,醉了,这次,我们就使用这种方法吧,然后将其它相关的都统统删掉
首先删除Startup
类中的ConfigureServices
方法中的相关配置
public void ConfigureServices(IServiceCollection services){services.AddMvc();services.AddEntityFrameworkSqlite().AddDbContext<HelloWorldDBContext>();services.AddIdentity<User, IdentityRole>().AddEntityFrameworkStores<HelloWorldDBContext>();}
其次在HelloWorldDBContext
类中重写方法OnConfiguring
,且删除带参数的构造函数
其实删除了带参数的构造函数,那么不带参数的构造函数也可以删除了,于是就变成了
using System;using Microsoft.EntityFrameworkCore;using Microsoft.AspNetCore.Identity.EntityFrameworkCore;using Microsoft.Extensions.Configuration;namespace HelloWorld.Models{public class HelloWorldDBContext:IdentityDbContext<User>{public DbSet<Employee> Employees { get; set; }protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder){optionsBuilder.UseSqlite("Data Source=blogging.db");}}}
这种方法我还没找到如何引用 Configuration 属性的方式,如果你知道,请麻烦告诉我下
重启下我们的应用程序,刷新下首页,看看是否正常输出
最佳实战
实际应用中,你千万不要像我这么激进,因为这两种方式是互补的关系,也就是说OnConfiguring()
方法可以覆写传递给HelloWorldDBContext(DbContextOptions<HelloWorldDBContext> options)
的连接
当一个应用需要连接多个数据库的时候,结合这两种方式非常有用,第一种方式用于默认的数据库,第二种方式用于特定的数据库
迁移 Identity 数据
好了,让我门言归正传吧,开始迁移 Identity 数据。其实前面的 EF 框架中我们已经迁移过一次了,不知道大家是否还记得如何迁移呢
首先停止我们的应用程序,不然会报错,因为我们使用的是文件系统数据库
其次打开控制台窗口 ( 终端或 Power Shell 或命令提示符),定位到我们的HelloWorld
项目下
$ cd ~/Developer/aspnetcore/HelloWorld/HelloWorld
我用的是 macOS,且我的 HelloWorld 保存在~/Developer/aspnetcore/HelloWorld/HelloWorld
然后使用ls
命名就可以列出当前目录下的所有文件和子目录
$ lsAppSettings.json Controllers HelloWorld.csproj Models Program.cs Properties Startup.cs Views bin obj wwwroot
如果你使用的是 Windows,且使用的不是 Power Shell,那么你应该使用
dir
命令而不是ls
命令
如果能看到HelloWorld.csproj
则说明处于正确的目录,否则你应该继续cd
到该目录下
然后可以运行下列命令创建迁移代码
dotnet ef migrations add InitialIdentity -v
运行结果如下
$ dotnet ef migrations add InitialIdentity -vUsing project '/Users/yufei/Developer/aspnetcore/HelloWorld/HelloWorld/HelloWorld.csproj'.Using startup project '/Users/yufei/Developer/aspnetcore/HelloWorld/HelloWorld/HelloWorld.csproj'.Writing '/Users/yufei/Developer/aspnetcore/HelloWorld/HelloWorld/obj/HelloWorld.csproj.EntityFrameworkCore.targets'...dotnet msbuild /target:GetEFProjectMetadata /property:EFProjectMetadataFile=/var/folders/yk/2446sljj6hn82nvzkdgxltmw0000gn/T/tmpbjHVNk.tmp /verbosity:quiet /nologo /Users/yufei/Developer/aspnetcore/HelloWorld/HelloWorld/HelloWorld.csprojWriting '/Users/yufei/Developer/aspnetcore/HelloWorld/HelloWorld/obj/HelloWorld.csproj.EntityFrameworkCore.targets'...dotnet msbuild /target:GetEFProjectMetadata /property:EFProjectMetadataFile=/var/folders/yk/2446sljj6hn82nvzkdgxltmw0000gn/T/tmpDgtTNf.tmp /verbosity:quiet /nologo /Users/yufei/Developer/aspnetcore/HelloWorld/HelloWorld/HelloWorld.csproj dotnet build /Users/yufei/Developer/aspnetcore/HelloWorld/HelloWorld/HelloWorld.csproj /verbosity:quiet /nologo Build succeeded. 0 Warning(s) 0 Error(s) Time Elapsed 00:00:03.64 dotnet exec --depsfile /Users/yufei/Developer/aspnetcore/HelloWorld/HelloWorld/bin/Debug/netcoreapp2.1/HelloWorld.deps.json --additionalprobingpath /Users/yufei/.nuget/packages --additionalprobingpath /usr/local/share/dotnet/sdk/NuGetFallbackFolder --runtimeconfig /Users/yufei/Developer/aspnetcore/HelloWorld/HelloWorld/bin/Debug/netcoreapp2.1/HelloWorld.runtimeconfig.json /usr/local/share/dotnet/sdk/2.1.301/DotnetTools/dotnet-ef/2.1.1/tools/netcoreapp2.1/any/tools/netcoreapp2.0/any/ef.dll migrations add InitialIdentity --assembly /Users/yufei/Developer/aspnetcore/HelloWorld/HelloWorld/bin/Debug/netcoreapp2.1/HelloWorld.dll --startup-assembly /Users/yufei/Developer/aspnetcore/HelloWorld/HelloWorld/bin/Debug/netcoreapp2.1/HelloWorld.dll --project-dir /Users/yufei/Developer/aspnetcore/HelloWorld/HelloWorld/ --language C# --working-dir /Users/yufei/Developer/aspnetcore/HelloWorld/HelloWorld --verbose --root-namespace HelloWorld Using assembly 'HelloWorld'. Using startup assembly 'HelloWorld'. Using application base '/Users/yufei/Developer/aspnetcore/HelloWorld/HelloWorld/bin/Debug/netcoreapp2.1'. Using working directory '/Users/yufei/Developer/aspnetcore/HelloWorld/HelloWorld'. Using root namespace 'HelloWorld'. Using project directory '/Users/yufei/Developer/aspnetcore/HelloWorld/HelloWorld/'. Finding DbContext classes... Finding IDesignTimeDbContextFactory implementations... Finding application service provider... Finding IWebHost accessor... Using environment 'Development'. Using application service provider from IWebHost accessor on 'Program'. Found DbContext 'HelloWorldDBContext'. Finding DbContext classes in the project... Using context 'HelloWorldDBContext'. Finding design-time services for provider 'Microsoft.EntityFrameworkCore.Sqlite'... Using design-time services from provider 'Microsoft.EntityFrameworkCore.Sqlite'. Finding design-time services referenced by assembly 'HelloWorld'. No referenced design-time services were found. Finding IDesignTimeServices implementations in assembly 'HelloWorld'... No design-time services were found. DetectChanges starting for 'HelloWorldDBContext'. DetectChanges completed for 'HelloWorldDBContext'. DetectChanges starting for 'HelloWorldDBContext'. DetectChanges completed for 'HelloWorldDBContext'. DetectChanges starting for 'HelloWorldDBContext'. DetectChanges completed for 'HelloWorldDBContext'. DetectChanges starting for 'HelloWorldDBContext'. DetectChanges completed for 'HelloWorldDBContext'. Writing migration to '/Users/yufei/Developer/aspnetcore/HelloWorld/HelloWorld/Migrations/0624040354_InitialIdentity.cs'. Writing model snapshot to '/Users/yufei/Developer/aspnetcore/HelloWorld/HelloWorld/Migrations/HelloWorldDBContextModelSnapshot.cs'. 'HelloWorldDBContext' disposed. Done. To undo this action, use 'ef migrations remove'
大概意思就是经过漫长的岁月,成功创建了迁移代码
这一步非常容易出错,如果你有任何错误,欢迎你在讨论区留下你包括的意见
Core 讨论区
创建迁移成功后,我们就可以使用下面的命令查看当前有多少迁移代码和它们的状态
$ dotnet ef migrations list
运行结果如下
$ dotnet ef migrations list0623011249_InitialCreate0624040354_InitialIdentity
可以看到总共有两个迁移代码,下面那个0624040354_InitialIdentity
就是我们刚刚创建
在解决方案管理器中我们还可以看到Migrations
又多了很多文件
接下来我们就要开始应用这些迁移来更新数据库,执行下面的命令来应用迁移代码
$ dotnet ef database update -v
执行以上命令,输出结果如下
$ dotnet ef database update -vUsing project '/Users/yufei/Developer/aspnetcore/HelloWorld/HelloWorld/HelloWorld.csproj'.Using startup project '/Users/yufei/Developer/aspnetcore/HelloWorld/HelloWorld/HelloWorld.csproj'.Writing '/Users/yufei/Developer/aspnetcore/HelloWorld/HelloWorld/obj/HelloWorld.csproj.EntityFrameworkCore.targets'...dotnet msbuild /target:GetEFProjectMetadata /property:EFProjectMetadataFile=/var/folders/yk/2446sljj6hn82nvzkdgxltmw0000gn/T/tmp6jVQsB.tmp /verbosity:quiet /nologo /Users/yufei/Developer/aspnetcore/HelloWorld/HelloWorld/HelloWorld.csprojWriting '/Users/yufei/Developer/aspnetcore/HelloWorld/HelloWorld/obj/HelloWorld.csproj.EntityFrameworkCore.targets'...dotnet msbuild /target:GetEFProjectMetadata /property:EFProjectMetadataFile=/var/folders/yk/2446sljj6hn82nvzkdgxltmw0000gn/T/tmpXNRfCA.tmp /verbosity:quiet /nologo /Users/yufei/Developer/aspnetcore/HelloWorld/HelloWorld/HelloWorld.csproj dotnet build /Users/yufei/Developer/aspnetcore/HelloWorld/HelloWorld/HelloWorld.csproj /verbosity:quiet /nologo Build succeeded. 0 Warning(s) 0 Error(s) Time Elapsed 00:00:04.59 dotnet exec --depsfile /Users/yufei/Developer/aspnetcore/HelloWorld/HelloWorld/bin/Debug/netcoreapp2.1/HelloWorld.deps.json --additionalprobingpath /Users/yufei/.nuget/packages --additionalprobingpath /usr/local/share/dotnet/sdk/NuGetFallbackFolder --runtimeconfig /Users/yufei/Developer/aspnetcore/HelloWorld/HelloWorld/bin/Debug/netcoreapp2.1/HelloWorld.runtimeconfig.json /usr/local/share/dotnet/sdk/2.1.301/DotnetTools/dotnet-ef/2.1.1/tools/netcoreapp2.1/any/tools/netcoreapp2.0/any/ef.dll database update --assembly /Users/yufei/Developer/aspnetcore/HelloWorld/HelloWorld/bin/Debug/netcoreapp2.1/HelloWorld.dll --startup-assembly /Users/yufei/Developer/aspnetcore/HelloWorld/HelloWorld/bin/Debug/netcoreapp2.1/HelloWorld.dll --project-dir /Users/yufei/Developer/aspnetcore/HelloWorld/HelloWorld/ --language C# --working-dir /Users/yufei/Developer/aspnetcore/HelloWorld/HelloWorld --verbose --root-namespace HelloWorld Using assembly 'HelloWorld'. Using startup assembly 'HelloWorld'. Using application base '/Users/yufei/Developer/aspnetcore/HelloWorld/HelloWorld/bin/Debug/netcoreapp2.1'. Using working directory '/Users/yufei/Developer/aspnetcore/HelloWorld/HelloWorld'. Using root namespace 'HelloWorld'. Using project directory '/Users/yufei/Developer/aspnetcore/HelloWorld/HelloWorld/'. Finding DbContext classes... Finding IDesignTimeDbContextFactory implementations... Finding application service provider... Finding IWebHost accessor... Using environment 'Development'. Using application service provider from IWebHost accessor on 'Program'. Found DbContext 'HelloWorldDBContext'. Finding DbContext classes in the project... Using context 'HelloWorldDBContext'. Finding design-time services for provider 'Microsoft.EntityFrameworkCore.Sqlite'... Using design-time services from provider 'Microsoft.EntityFrameworkCore.Sqlite'. Finding design-time services referenced by assembly 'HelloWorld'. No referenced design-time services were found. Finding IDesignTimeServices implementations in assembly 'HelloWorld'... No design-time services were found. Migrating using database 'main' on server 'blogging.db'. Opening connection to database 'main' on server 'blogging.db'. Opened connection to database 'main' on server '/Users/yufei/Developer/aspnetcore/HelloWorld/HelloWorld/blogging.db'. Executing DbCommand [Parameters=[], CommandType='Text', CommandTimeout='30'] PRAGMA foreign_keys=ON; Executed DbCommand (33ms) [Parameters=[], CommandType='Text', CommandTimeout='30'] PRAGMA foreign_keys=ON; Opening connection to database 'main' on server 'blogging.db'. Opened connection to database 'main' on server '/Users/yufei/Developer/aspnetcore/HelloWorld/HelloWorld/blogging.db'. Executing DbCommand [Parameters=[], CommandType='Text', CommandTimeout='30'] PRAGMA foreign_keys=ON; Executed DbCommand (0ms) [Parameters=[], CommandType='Text', CommandTimeout='30'] PRAGMA foreign_keys=ON; Executing DbCommand [Parameters=[], CommandType='Text', CommandTimeout='30'] SELECT COUNT(*) FROM "sqlite_master" WHERE "name" = '__EFMigrationsHistory' AND "type" = 'table'; Executed DbCommand (9ms) [Parameters=[], CommandType='Text', CommandTimeout='30'] SELECT COUNT(*) FROM "sqlite_master" WHERE "name" = '__EFMigrationsHistory' AND "type" = 'table'; Closing connection to database 'main' on server '/Users/yufei/Developer/aspnetcore/HelloWorld/HelloWorld/blogging.db'. Closed connection to database 'main' on server 'blogging.db'. Opening connection to database 'main' on server 'blogging.db'. Opened connection to database 'main' on server '/Users/yufei/Developer/aspnetcore/HelloWorld/HelloWorld/blogging.db'. Executing DbCommand [Parameters=[], CommandType='Text', CommandTimeout='30'] PRAGMA foreign_keys=ON; Executed DbCommand (0ms) [Parameters=[], CommandType='Text', CommandTimeout='30'] PRAGMA foreign_keys=ON; Opening connection to database 'main' on server 'blogging.db'. Opened connection to database 'main' on server '/Users/yufei/Developer/aspnetcore/HelloWorld/HelloWorld/blogging.db'. Executing DbCommand [Parameters=[], CommandType='Text', CommandTimeout='30'] PRAGMA foreign_keys=ON; Executed DbCommand (0ms) [Parameters=[], CommandType='Text', CommandTimeout='30'] PRAGMA foreign_keys=ON; Executing DbCommand [Parameters=[], CommandType='Text', CommandTimeout='30'] SELECT COUNT(*) FROM "sqlite_master" WHERE "name" = '__EFMigrationsHistory' AND "type" = 'table'; Executed DbCommand (0ms) [Parameters=[], CommandType='Text', CommandTimeout='30'] SELECT COUNT(*) FROM "sqlite_master" WHERE "name" = '__EFMigrationsHistory' AND