当前位置:首页 > 技能相关 > .NET > 正文内容

EFCore:谈谈数据迁移、回退等方面

admin1年前 (2023-12-25).NET5010 修订时间:2023-12-25 22:55:54

在实际的项目,ER关系模型确定后,基本上可以确定数据库的框架。随着项目的推进或者需求的变化,往往需要修改实体关系(例如:新增字段,删除字段,增加新表等)。
在EFCore中,我们可以采用如下方式进行迁移:

 Add-Migration 迁移名称//VisualStudio中使用
 dotnet ef migrations add 迁移名称 //.NETCore CLI里使用

执行上述命令后,在项目文件里会生成一个叫Migrations的文件夹。

如果是第一次迁移,我们一般会在这个文件夹下,出现两个类,一个分步类,这个类主要做此次迁移的具体工作,一个是数据库快照类。

迁移类里主要有3个方法,其中一个分步类是Up和Down方法还有一个BuildTargetModel方法。

1、添加迁移

1.1增加迁移先进行的操作主要如下:

<1>编译程序,(注意:当前程序内存在编译错误,就无法迁移),
<2>将新的模型与当前数据库快照进行对比,从而从而生成新迁移文件的Up和Down方法。

<3>增加迁移后必须通过Update-DataBase 才能成功应用到数据库中。

1.2示例

修改下Teacher 实体类,增加一个字段为Age,代码如下:

    public class Teacher
    {
        public int TeacherId { get; set; }
        public string Name { get; set; }
        public string Title { get; set; }

        public int Age { get; set; }

        //一对多
        public IList<Course> Courses { get; set; } = new List<Course>();
    }

添加一个Add-Migration AddTeacherAge,然后Update-Database;

image.png

在修改或者删除某个属性的时候,会有警告提示,我们的操作可能导致数据库数据丢失。

迁移删除以及回退

在迁移的更改还未应用到数据库的时候可以删除迁移,但是如果已经使用Update-Database即将迁移更改应用到数据库就不能采用Remove-Migration 删除。但是我们可以采用Update-DataBase回退到前面一个应用,如下,我们使用 下面的命令回退到给Teacher 增加Age的应用这个时候数据库表Student应该是有Age属性,EFMigrationsHistory表的记录也会修改。

image.png

Update-DataBase 20231225143649_AddTeacherAge

2、通过Sql脚本迁移

已经上线的项目,再通过Update-DataBase就会很麻烦。我们可以通过导出Sql脚本,来进行数据库的更改。我们再给Teacher这个类,加回Age这个属性。

2.1修改下Teacher 实体类,增加一个字段为Age,代码如下:

    public class Teacher
    {
        public int TeacherId { get; set; }
        public string Name { get; set; }
        public string Title { get; set; }

        public int Age { get; set; }

        //一对多
        public IList<Course> Courses { get; set; } = new List<Course>();
    }

2.2执行Script-Migration,获得代码如下:

CREATE TABLE IF NOT EXISTS `__EFMigrationsHistory` (
    `MigrationId` varchar(150) CHARACTER SET utf8mb4 NOT NULL,
    `ProductVersion` varchar(32) CHARACTER SET utf8mb4 NOT NULL,
    CONSTRAINT `PK___EFMigrationsHistory` PRIMARY KEY (`MigrationId`)
) CHARACTER SET utf8mb4;

START TRANSACTION;

ALTER DATABASE CHARACTER SET utf8mb4;

CREATE TABLE `Students` (
    `StudentId` int NOT NULL AUTO_INCREMENT,
    `Name` varchar(50) CHARACTER SET utf8mb4 NOT NULL,
    `Sex` varchar(5) CHARACTER SET utf8mb4 NOT NULL,
    `Age` int NOT NULL,
    CONSTRAINT `PK_Students` PRIMARY KEY (`StudentId`)
) CHARACTER SET utf8mb4;

CREATE TABLE `Teachers` (
    `TeacherId` int NOT NULL AUTO_INCREMENT,
    `Name` varchar(50) CHARACTER SET utf8mb4 NULL,
    `Title` varchar(50) CHARACTER SET utf8mb4 NULL,
    CONSTRAINT `PK_Teachers` PRIMARY KEY (`TeacherId`)
) CHARACTER SET utf8mb4;

CREATE TABLE `Addresses` (
    `StudentAddressId` int NOT NULL AUTO_INCREMENT,
    `Address` varchar(500) CHARACTER SET utf8mb4 NOT NULL,
    `City` varchar(100) CHARACTER SET utf8mb4 NOT NULL,
    `StudentId` int NOT NULL,
    CONSTRAINT `PK_Addresses` PRIMARY KEY (`StudentAddressId`),
    CONSTRAINT `FK_Addresses_Students_StudentId` FOREIGN KEY (`StudentId`) REFERENCES `Students` (`StudentId`) ON DELETE CASCADE
) CHARACTER SET utf8mb4;

CREATE TABLE `Courses` (
    `CourseId` int NOT NULL AUTO_INCREMENT,
    `Name` varchar(50) CHARACTER SET utf8mb4 NULL,
    `TeacherId` int NULL,
    CONSTRAINT `PK_Courses` PRIMARY KEY (`CourseId`),
    CONSTRAINT `FK_Courses_Teachers_TeacherId` FOREIGN KEY (`TeacherId`) REFERENCES `Teachers` (`TeacherId`) ON DELETE RESTRICT
) CHARACTER SET utf8mb4;

CREATE TABLE `CourseStudent` (
    `CoursesCourseId` int NOT NULL,
    `StudentsStudentId` int NOT NULL,
    CONSTRAINT `PK_CourseStudent` PRIMARY KEY (`CoursesCourseId`, `StudentsStudentId`),
    CONSTRAINT `FK_CourseStudent_Courses_CoursesCourseId` FOREIGN KEY (`CoursesCourseId`) REFERENCES `Courses` (`CourseId`) ON DELETE CASCADE,
    CONSTRAINT `FK_CourseStudent_Students_StudentsStudentId` FOREIGN KEY (`StudentsStudentId`) REFERENCES `Students` (`StudentId`) ON DELETE CASCADE
) CHARACTER SET utf8mb4;

CREATE UNIQUE INDEX `IX_Addresses_StudentId` ON `Addresses` (`StudentId`);

CREATE INDEX `IX_Courses_TeacherId` ON `Courses` (`TeacherId`);

CREATE INDEX `IX_CourseStudent_StudentsStudentId` ON `CourseStudent` (`StudentsStudentId`);

INSERT INTO `__EFMigrationsHistory` (`MigrationId`, `ProductVersion`)
VALUES ('20231225134819_Initial', '5.0.17');

COMMIT;

START TRANSACTION;

ALTER TABLE `Teachers` ADD `Age` int NOT NULL DEFAULT 0;

INSERT INTO `__EFMigrationsHistory` (`MigrationId`, `ProductVersion`)
VALUES ('20231225143649_AddTeacherAge', '5.0.17');

COMMIT;

上面是全部的SQL代码,我们可以摘取自己想要的代码区实现具体数据库的修改。

 您阅读本篇文章共花了: 

免责声明
本站内容均为博客主本人日常使用记录的存档,如侵犯你的权益请联系:lifei@zaiheze.com 546262132@qq.com 沟通删除事宜。本站仅带访问端口形式使用,已杜绝搜索引擎爬取。

扫描二维码推送至手机访问。

版权声明:本文由LIFEI - blog发布,如需转载请注明出处。

本文链接:http://www.lifeiai.com/?id=349

分享给朋友:

发表评论

访客

◎欢迎参与讨论,请在这里发表您的看法和观点。