一.管理数据库架构概述

EF Core 提供两种主要方法来保持 EF Core 模型和数据库架构同步。一是以 EF Core 模型为基准,二是以数据库为基准。

  (1)如果希望以 EF Core 模型为准,请使用迁移。 对 EF Core 模型进行更改时,此方法会以增量方式将相应架构更改应用到数据库,以使数据库保持与 EF Core 模型兼容。

   (2)如果希望以数据库架构为准,请使用反向工程。 使用此方法,可通过将数据库架构反向工程到 EF Core 模型来生成相应的 DbContext 和实体类型。

  

  1.1. 迁移概述

    在开发期间,数据模型发生更改后,会与数据库不同步。 虽然可以删除该数据库,让 EF 创建一个新的数据库来匹配该模型,但此过程会导致数据丢失。迁移作用是指:在 EF Core 中使用迁移功能,能够以递增方式更新数据库架构,使其与应用程序的数据模型保持同步,同时保留数据库中的现有数据。

      迁移包括 命令行工具和API,可协助执行以下任务:

       (1) 创建迁移。 生成数据库更新的代码脚本,用来准备将应用模型同步到数据库。

       (2) 更新数据库。通过“创建迁移”的代码脚本,同步数据库。

       (3) 自定义迁移代码。有时需要修改或补充应用模型,并同步数据库。

       (4) 删除迁移。 删除生成的迁移版本(该版本没有更新到数据库)。

       (5) 还原迁移。 撤消回滚数据库更改(该版本已更新到数据库)。

        (6) 生成 SQL脚本。 可能需要一个脚本来更新生产数据库,或者对迁移代码进行故障排除。

       (7) 在运行时应用迁移。 如果在设计期间更新和运行脚本不是最佳选项时,可在运行时调用 Migrate() 方法。

  2.1 安装命令工具

    (1)对于Visual Studio开发,建议使用Package Manager Console(程序包管理器控制台)工具,使用windows上的PowerShell脚本。

(2)对于其他开发环境,请选择.NET Core CLI工具,使用dotnet命令是跨平台的。

    本篇使用Visual Studio开发,使用Package Manager Console工具来进行迁移管理,用PowerShell脚本,并附带上跨平台管理 的dotnet命令。还是使用Blog和Post应用模型来演示。

二. 命令演示

  2.1  创建迁移

    在定义初始化模型后,即应创建数据库。 若要添加初始迁移,请运行以下命令,其中InitialCreate属于自定义迁移类名,它继承了DbContext。

PowerShell dotnet
Add-Migration InitialCreate dotnet ef migrations add InitialCreate

    关于准备工作和创建迁移注意事项这里不在说明,请参考“asp.net core 系列 20 EF基于数据模型创建数据库”。在开发中,一般都是使用多层架构,这里新建了一个实体类库EFGetStarted.AspNetCore.Model,在web项目的"依赖项"上右击添加引用,选择实体类库。

    在实体类库上安装数据库提供程序。创建三个类BloggingContext类(继承DbContext)、Blog实体类、Post实体类。接着使用Package Manager Console工具运行Add-Migration InitialCreate命令。如下所图所示:

    当运行了Add-Migration InitialCreate后,将在项目中生成一个Migrations 文件夹,并在其中生成三个文件,文件名中的时间戳有助于保证文件按时间顺序排列:

      (1) 00000000000000_InitialCreate.cs--主迁移文件。 包含应用迁移所需的操作 Up() 和还原迁移所需的操作Down() 。

      (2) 00000000000000_InitialCreate.Designer.cs--迁移元数据文件。 包含 EF 所用的信息,如给实体类型构建属性、主键、外键、索引、映射到数据表,主体和依赖关系等等,如下所示:

      (3) BloggingContextModelSnapshot.cs - 当前模型的快照。用于确定添加下一次迁移时更改的内容(用于递增更新)。

  2.2 更新数据库

    接下来,将迁移应用于数据库以创建架构。命令如下:

PowerShell dotnet
Update-Database InitialCreate dotnet ef database update InitialCreate

    注意:更新到数据库,需要创建数据库的连接。项目中配置数据库连接,一般是存放在web项目的appsettings.json文件中,并在Startup类中调用。这里演示是直接写死在Startup类代码中,如下所示:

     var connection = "Data Source = {ip}; Initial Catalog = EFGetStarted.AspNetCore.NewDb; User ID = hsr;Password =js*2015;";
services.AddDbContext<BloggingContext>
(options => options.UseSqlServer(connection));

    在Package Manager Console工具中,运行Update-Database InitialCreate命令,同步到数据库,如下所示:

  2.3 自定义迁移代码

    更改 EF Core 模型后,数据库架构可能不同步。为使其保持最新,请再添加一个新的迁移。例如我在Blog实体类,新添加了一个属性,和修改了一个属性的CLR类型。

    public class Blog
{
public int BlogId { get; set; } //将string 改为char
public char Name { get; set; }
//新增一个属性
public string Title { get; set; } public string Url { get; set; }
public ICollection<Post> Posts { get; set; }
}

    运行Add-Migration  Blog_Modifier,添加一个新的迁移

    再运行Update-Database Blog_Modifier,同步到数据库中。char类型的Name生成后默认是nvarchar(1),对于指定属性的长度,参考上篇关系数据库建模。

    查看数据库的迁移历史,可以查看到迁移ID  MigrationId,其中20190222031152_Blog_Modifier 是最新的迁移同步到数据库的版本。

    2.3.1 空迁移

      有时模型未变更,直接添加迁移也很有用处。 在这种情况下,添加新迁移会创建一个带空类的代码文件。可以自定义此迁移,执行与 EF Core 模型不直接相关的操作。 可能需要通过此方式管理的一些事项包括:

        (1)全文搜索

        (2)函数

        (3)存储过程

        (4)触发器

        (5)视图

      通过上面操作,以Code First模式下,不需要对数据库进行直接操作,在数据库建模上,DBA以检查数据库架构为主。

  

  2.4 删除迁移

    有时修,项目在添加迁移后,意识到需要在应用迁移前对 EF Core 模型作出其他更改。 要删除上个迁移。 删除迁移是使用了Add-Migration生成迁移后,还没有应用Update-Database同步到数据库架构。请使用如下命令。

PowerShell dotnet
Remove-Migration  Name dotnet ef migrations remove Name

  2.5 还原迁移

    如果已经对数据库应用一个迁移(或多个迁移),但需将其复原(回滚),需要使用更新数据库命令,并指定回滚时的目标迁移名称。下面还原到迁移名称InitialCreate状态时。运行PM> Update-Database InitialCreate后,数据库同步,回到了最初InitialCreate迁移状态,数据库Blogs表还原到了当初。

  2.6 生成 SQL 脚本

    调试迁移或将其部署到生产数据库时,生成一个 SQL 脚本很有帮助。 之后可进一步检查该脚本的准确性,并对其作出调整以满足生产数据库的需求。 该脚本还可与部署技术结合使用。 基本命令如下。

PowerShell dotnet
Script-Migration dotnet ef migrations script

    Script-Migration参数介绍:

-From<String> 开始迁移。迁移可以通过名称或ID来标识。数字0是一种特殊情况,这意味着在第一次迁移之前。默认值为0
-To<String> 结束迁移。默认值为最后一次迁移。
-Idempotent 生成可在任何迁移时在数据库上使用的脚本。
-Output <String> 要将结果写入的文件。如果省略该参数,则在创建应用程序运行时文件的文件夹中使用生成的名称创建文件,例如:/obj/Debug/netcoreapp2.1/ghbkztfz.sql/

    下面的示例使用InitialCreate迁移版本,创建一个sql脚本文件,输出到D盘。

    PM> Script-Migration -From 0  -To InitialCreate -Output D:\InitialCreate.sql
IF OBJECT_ID(N'[__EFMigrationsHistory]') IS NULL
BEGIN
CREATE TABLE [__EFMigrationsHistory] (
[MigrationId] nvarchar(150) NOT NULL,
[ProductVersion] nvarchar(32) NOT NULL,
CONSTRAINT [PK___EFMigrationsHistory] PRIMARY KEY ([MigrationId])
);
END; GO CREATE TABLE [Blogs] (
[BlogId] int NOT NULL IDENTITY,
[Name] nvarchar(max) NULL,
[Url] nvarchar(max) NULL,
CONSTRAINT [PK_Blogs] PRIMARY KEY ([BlogId])
); GO CREATE TABLE [Posts] (
[PostId] int NOT NULL IDENTITY,
[Title] nvarchar(max) NULL,
[Content] nvarchar(max) NULL,
[BlogId] int NOT NULL,
CONSTRAINT [PK_Posts] PRIMARY KEY ([PostId]),
CONSTRAINT [FK_Posts_Blogs_BlogId] FOREIGN KEY ([BlogId]) REFERENCES [Blogs] ([BlogId]) ON DELETE CASCADE
); GO CREATE INDEX [IX_Posts_BlogId] ON [Posts] ([BlogId]); GO INSERT INTO [__EFMigrationsHistory] ([MigrationId], [ProductVersion])
VALUES (N'20190222024519_InitialCreate', N'2.2.1-servicing-10028'); GO

    

  2.7 在运行时应用迁移

    某些应用程序可能希望在启动或首次运行期间在运行时应用迁移。使用该Migrate()方法执行此操作。

    myDbContext.Database.Migrate();    

    注意:此方法并不适合所有场景。 尽管此方法非常适合具有本地数据库的应用,但是大多数应用程序需要更可靠的部署策略,例如生成 SQL 脚本。

      请勿在 Migrate() 前调用 EnsureCreated()。 EnsureCreated() 会绕过迁移创建架构,这会导致 Migrate() 失败。

  参考文献:

    EF迁移

    Package Manager Console

asp.net core系列 30 EF管理数据库架构--必备知识 迁移的更多相关文章

  1. asp.net core系列 31 EF管理数据库架构--必备知识 反向工程

    一.   反向工程 反向工程是基于数据库架构,生成的实体类和DbContext类代码的过程,对于Visual Studio开发,建议使用PMC.对于其他开发环境,请选择.NET Core CLI工具( ...

  2. asp.net core 系列 21 EF现有数据库进行反向工程

    一.概述 在上篇中使用EF基于数据模型创建数据库,  本篇继续使用 EF  基于数据库创建数据模型.  实现对已有数据库进行反向工程,来构建数据访问的 ASP.NET Core MVC 应用程序.已有 ...

  3. asp.net core 系列 22 EF(连接字符串,连接复原,DbContext)

    一.连接字符串 在上二篇中,ASP.NET Core 应用程序连接字符串是写死在ConfigureServices代码中,下面介绍通过配置来实现.连接字符串可以存储在 appsettings.json ...

  4. asp.net core 系列 20 EF基于数据模型创建数据库

    一.概述 本章使用 Entity Framework Core 构建执行基本数据访问的 ASP.NET Core MVC 应用程序.使用迁移(migrations)基于数据模型创建数据库,是一种cod ...

  5. asp.net core系列 29 EF模型配置(查询类型,关系数据库建模)

    一.查询类型 此功能是EF Core 2.1中的新功能. EF Core除了实体类型之外,EF Core模型还可以包含查询类型,这些查询类型是针对“未映射到实体类型”的数据获取.比如视图,或只读数据表 ...

  6. asp.net core系列 28 EF模型配置(字段,构造函数,拥有实体类型)

    一. 支持字段 EF允许读取或写入字段而不是一个属性.在使用实体类时,用面向对象的封装来限制或增强应用程序代码对数据访问的语义时,这可能很有用.无法使用数据注释配置.除了约定,还可以使用Fluent ...

  7. asp.net core系列 35 EF保存数据(2) -- EF系列结束

    一.事务 (1) 事务接着上篇继续讲完.如果使用了多种数据访问技术,来访问关系型数据库,则可能希望在这些不同技术所执行的操作之间共享事务.下面示例显示了如何在同一事务中执行 ADO.NET SqlCl ...

  8. asp.net core系列 34 EF保存数据(1)

    一. 基本数据 每个EF上下文实例都有一个 ChangeTracker(更改跟踪器),它负责跟踪需要写入数据库的更改. 当更改实体类的实例时(修改属性,删除实例,新建实例等),这些更改会记录在 Cha ...

  9. asp.net core系列 33 EF查询数据 (2)

    一. 原生SQL查询 接着上篇讲.通过 Entity Framework Core 可以在使用关系数据库时下降到原始 SQL 查询. 在无法使用 LINQ 表达要执行的查询时,或因使用 LINQ 查询 ...

随机推荐

  1. [dotnet] 封装一个同时支持密码/安全密钥认证的SFTP下载器,简单易用。

    前言 最近在开发订单对账系统,先从各种支付平台获取订单销售数据,然后与公司商城订单数据进行对账兜底.总体上,各个支付平台提供数据的方式分为两类,一般以接口的方式提供实时数据,比如:webservice ...

  2. 【Python实践-6】将不规范的英文名字,变为首字母大写,其他小写的规范名字

    #利用map()函数,把用户输入的不规范的英文名字,变为首字母大写,其他小写的规范名字. def f1(s): s=s.capitalize() return s list1= ['adam', 'L ...

  3. Spring Boot 入门教程 | 图文讲解

    目录 一.Spring Boot 是什么 二.为什么要使用 Spring Boot 三.快速入门 3.1 创建 Spring Boot 项目 3.2 项目结构 3.3 引入 Web 依赖 3.4 编写 ...

  4. DDD领域驱动设计理论篇 - 学习笔记

    一.Why DDD? 在加入X公司后,开始了ASP.NET Core+Docker+Linux的技术实践,也开始了微服务架构的实践.在微服务的学习中,有一本微软官方出品的<.NET微服务:容器化 ...

  5. 初探机器学习之使用百度AI服务实现图片识别与相似图片

    一.百度云AI服务 最近在调研一些云服务平台的AI(人工智能)服务,了解了一下阿里云.腾讯云和百度云.其中,百度云提供了图像识别及图像搜索,而且还细分地提供了相似图片这项服务,比较符合我的需求,且百度 ...

  6. 目前比较流行的Python量化开源框架汇总(交易+风险分析工具)

     注:点击框架名称通往Github talib talib的简称是Technical Analysis Library,主要功能是计算行情数据的技术分析指标 numpy 介绍:一个用python实现的 ...

  7. 我敢说你不一定完全理解try 块,catch块,finally 块中return的执行顺序

    大家好,今天我们来讲一个笔试和面试偶尔都会问到的问题,并且在工作中不知道原理,也会造成滥用. 大家可能都知道,try 块用来捕获异常,catch块是处理try块捕获的异常,finally 块是用来关闭 ...

  8. DSAPI多功能.NET函数库组件

    DSAPI.dll不定期更新,增加功能,故无法每次都发到网上,如果需要获得最新版DSAPI.dll的,请到QQ群:419130936群共享里下载. 简介     dsapi.dll是一款基于.net平 ...

  9. 动态路由协议(RIP)

    虽然静态路由在某些时刻很有用,但是必须手工配置每条路由条目,对于大中型的网络或拓补经常发生变化的清空,配置和维护静态路由的工作量就变得非常繁重,而且不小心还容易出错,因此就需要一种不需要手工配置的路由 ...

  10. 正向代理&反向代理 简(fu)明(za)解释

    最近写的东西越来越偏向Web程序员了··· 你想读懂本篇,就要知道什么是Web服务器——装在世界上某个机房里某台机器里某个操作系统里的一个,对外(公网或者你能访问)服务各种你需要的信息的软件! 它可以 ...