1.使用迁移可以对当前数据库执行更高的编号的迁移,这个操作叫UP,
就是刚刚执行的迁移操作,
2.也可以执行数据库回退的迁移,这个叫down,就是将数据库回溯到之前的状态,既然要回退,就要删掉之前改变的东西
首先引入两个包:
Microsoft.EntityFrameworkCore.SqlServer
Microsoft.EntityFrameworkCore.Tools
1.创建DbContext类
class MyDbContext:DbContext
{
public DbSet<Person> Persons { get; set; }
protected override void OnConfiguring (DbContextOptionsBuilder optionsBuilder)
{
base.OnConfiguring(optionsBuilder);
optionsBuilder.UseSqlServer("server=localhost;uid=sa;pwd=123456;database=demo2_Migration;");
}
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
base.OnModelCreating(modelBuilder);
modelBuilder.ApplyConfigurationsFromAssembly(this.GetType().Assembly);
}
}
2.创建一个实体
class Person
{
public long Id { get; set; }
public string Name { get; set; }
}
3.添加Person 配置
class PersonConfig:IEntityTypeConfiguration<Person>
{
public void Configure(EntityTypeBuilder<Person> builder)
{
builder.ToTable("T_Persons");
builder.Property(b => b.Name).IsRequired();
}
}
基本框架搭建完毕
4.执行迁移
public partial class InitDb : Migration
{
//一开始的项目是没有数据库的,所以向上迁移的会生成一个数据库
protected override void Up(MigrationBuilder migrationBuilder)
{
//创建一个表
migrationBuilder.CreateTable(
//名字的T_Persons
name: "T_Persons",
columns: table => new
{
//id设置为long类型,且是Annotation(自增)字段,
Id = table.Column<long>(nullable: false)
.Annotation("SqlServer:Identity", "1, 1"),
Name = table.Column<string>(nullable: false)
},
constraints: table =>
{
//主键
table.PrimaryKey("PK_T_Persons", x => x.Id);
});
}
//当执行向下操作时会删除表,
protected override void Down(MigrationBuilder migrationBuilder)
{
migrationBuilder.DropTable(
name: "T_Persons");
}
5.再次添加一个字段Height,并执行迁移AddHeight
分析Migration
public partial class AddHeight : Migration
{
//向上迁移,会增加一列
protected override void Up(MigrationBuilder migrationBuilder)
{
migrationBuilder.AddColumn<double>(
name: "Height",
table: "T_Persons",
nullable: false,
defaultValue: 0.0);
}
protected override void Down(MigrationBuilder migrationBuilder)
{
//向下迁移就会删除T_Persons表中的Height列
migrationBuilder.DropColumn(
name: "Height",
table: "T_Persons");
}
数据库更新或者回退到XXX的这个迁移状态下,而迁移的脚本却不会改变。
极其不建议手动删除迁移脚本,会破坏脚本的上下关系,可以用第二条操作。
首先是数据库原状态,有三个属性
执行 update-database InitDb进行回退
尝试回退到InitDb状态下
执行完毕回到了InitDb状态下了
删除最后一次迁移脚本
会显示出最新一次的迁移脚本,然后这可以拿去数据库执行,而EFCore也是拿这个去执行的操作,因为之前的Height脚本删除了,所以打印的是InitDb脚本。
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 [T_Persons] (
[Id] bigint NOT NULL IDENTITY,
[Name] nvarchar(max) NOT NULL,
CONSTRAINT [PK_T_Persons] PRIMARY KEY ([Id])
);
GO
INSERT INTO [__EFMigrationsHistory] ([MigrationId], [ProductVersion])
VALUES (N'20211219023259_InitDb', N'3.1.0');
GO
ALTER TABLE [T_Persons] ADD [Height] float NOT NULL DEFAULT 0.0E0;
GO
INSERT INTO [__EFMigrationsHistory] ([MigrationId], [ProductVersion])
VALUES (N'20211219025609_AddHeight', N'3.1.0');
GO
为什么有了Update-database还要这个,让EFcore做就行了?
因为,Update-database这种只适合开发环境,不适合生产环境,比如某些要求安全性高,不方便对外公开的企业的数据库,不能让开发员直接连接,就要生成脚本,让别人的操作员执行脚本,还有审计的需要脚本以文本展示出来。