实验环境:
- window10 64位
- vs2019 Enterprise 16.7.4
- .netcoreapp3.1
- EntityFrameworkCore 3.1.9
- sqlserver 2008 R2
实验目的:
- 验证EntityFrameworkCore的增删改查
说明:
使用“EntityFrameworkCore”是有两种方式:DBFirst和CodeFirst,小型项目可以用CodeFirst,大型项目一般用DBFirst,这里主要采用DBFirst
下面采用DBFirst实验,最后说明CodeFirst
一、准备数据库
新建表student、book、teacher、studentbook、studentinfo
他们之间存在1对多、多对多的关系:
- student和book通过studentbook实现多对多
- studentinfo与student是一对一
-
book与teacher是一对多
建库脚本如下:
--***************先清空具有外键的表:studentbook/studentinfo/teacher ***********
if exists (select 1
from sysobjects
where id = object_id('studentbook')
and type = 'U')
begin
drop table studentbook
print '已删除表:studentbook'
end
go
if exists (select 1
from sysobjects
where id = object_id('studentinfo')
and type = 'U')
begin
drop table studentinfo
print '已删除表:studentinfo'
end
go
if exists (select 1
from sysobjects
where id = object_id('teacher')
and type = 'U')
begin
drop table teacher
print '已删除表:teacher'
end
go
--**************************************
--****************<book>**************
if exists (select 1
from sysobjects
where id = object_id('book')
and type = 'U')
begin
drop table book
print '已删除表:book'
end
go
create table [book] (
[id] int not null unique,
[name] varchar(50)
)
ALTER TABLE [book] ADD CONSTRAINT PK_gene_book_id PRIMARY KEY(id)
print '已创建:book'
go
--****************</book>**************
--****************<student>**************
if exists (select 1
from sysobjects
where id = object_id('student')
and type = 'U')
begin
drop table student
print '已删除表:student'
end
go
create table [student] (
[id] int not null unique,
[name] varchar(50) not null ,
[addr] varchar(500) ,
[birth] datetime ,
[img] image
)
ALTER TABLE [student] ADD CONSTRAINT PK_gene_student_id PRIMARY KEY(id)
print '已创建:student'
go
--****************</student>**************
--****************<studentbook>**************
create table [studentbook] (
[sid] int not null ,
[bookid] int not null
)
ALTER TABLE [studentbook] ADD CONSTRAINT PK_gene_studentbook_sid_bookid PRIMARY KEY([sid],[bookid])
--************外键约束<FK_userbook_userbook>*****************
ALTER TABLE studentbook ADD CONSTRAINT FK_userbook_userbook FOREIGN KEY(sid) REFERENCES test.dbo.student (id) ON DELETE NO ACTION ON UPDATE NO ACTION
--************外键约束</FK_userbook_userbook>*****************
--************外键约束<FK_userbook_userbook1>*****************
ALTER TABLE studentbook ADD CONSTRAINT FK_userbook_userbook1 FOREIGN KEY(bookid) REFERENCES test.dbo.book (id) ON DELETE NO ACTION ON UPDATE NO ACTION
--************外键约束</FK_userbook_userbook1>*****************
print '已创建:studentbook'
go
--****************</studentbook>**************
--****************<studentinfo>**************
create table [studentinfo] (
[sid] int not null unique,
[indate] datetime ,
[type] int ,
[desc] varchar(500)
)
ALTER TABLE [studentinfo] ADD CONSTRAINT PK_gene_studentinfo_sid PRIMARY KEY(sid)
--************外键约束<FK_studentinfo_student>*****************
ALTER TABLE studentinfo ADD CONSTRAINT FK_studentinfo_student FOREIGN KEY(sid) REFERENCES test.dbo.student (id) ON DELETE NO ACTION ON UPDATE NO ACTION
--************外键约束</FK_studentinfo_student>*****************
print '已创建:studentinfo'
go
--****************</studentinfo>**************
--****************<teacher>**************
create table [teacher] (
[id] int not null unique,
[name] varchar(50) not null ,
[bid] int not null
)
ALTER TABLE [teacher] ADD CONSTRAINT PK_gene_teacher_id PRIMARY KEY(id)
--************外键约束<FK_teacher_teacher>*****************
ALTER TABLE teacher ADD CONSTRAINT FK_teacher_teacher FOREIGN KEY(bid) REFERENCES test.dbo.book (id) ON DELETE NO ACTION ON UPDATE NO ACTION
--************外键约束</FK_teacher_teacher>*****************
print '已创建:teacher'
go
--****************</teacher>**************
二、准备工程
打开vs2019,新建两个.netcore控制台项目如下:
![](https://img.laitimes.com/img/__Qf2AjLwojIjJCLyojI0JCLiAzNfRHLGZkRGZkRfJ3bs92YsYTMfVmepNHL9smeNNTW65EMBRVT3V1MMBjVtJWd0ckW65UbM5WOHJWa5kHT20ESjBjUIF2X0hXZ0xCMx81dvRWYoNHLrdEZwZ1Rh5WNXp1bwNjW1ZUba9VZwlHdssmch1mclRXY39CXldWYtlWPzNXZj9mcw1ycz9WL49zZuBnLzgTM4AjMzYTMyETOwkTMwIzLc52YucWbp5GZzNmLn9Gbi1yZtl2Lc9CX6MHc0RHaiojIsJye.png)
编辑dbfirst工程,添加EntityFrameworkCore包:
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>netcoreapp3.1</TargetFramework>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Microsoft.EntityFrameworkCore.SqlServer" Version="3.1.10" />
<PackageReference Include="Microsoft.EntityFrameworkCore.Tools" Version="3.1.10">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers</IncludeAssets>
</PackageReference>
<PackageReference Include="Microsoft.Extensions.Logging.Console" Version="3.1.10" />
<PackageReference Include="Microsoft.Extensions.Logging.Debug" Version="3.1.10" />
</ItemGroup>
</Project>
或者使用vs安装如下:
注意:上面包的作用
- Microsoft.EntityFrameworkCore.SqlServer:efcore操作sqlserver;
- Microsoft.EntityFrameworkCore.Tools:efcore的工具包,可用来做dbfirst/codefirst
- Microsoft.Extensions.Logging.Console:将日志输出到控制台
- Microsoft.Extensions.Logging.Debug:将日志输出到vs的调试窗口
三、从数据库生成模型代码
打开包管理控制台窗口:
执行命令:
Scaffold-DbContext "Data Source = .;Initial Catalog = test;User Id = sa;Password = 123456;" Microsoft.EntityFrameworkCore.SqlServer -OutputDir Models
完成后观察项目中自动生成了的代码:
Book.cs:
using System;
using System.Collections.Generic;
namespace dbfirst.Models
{
public partial class Book
{
public Book()
{
Studentbook = new HashSet<Studentbook>();
Teacher = new HashSet<Teacher>();
}
public int Id { get; set; }
public string Name { get; set; }
public virtual ICollection<Studentbook> Studentbook { get; set; }
public virtual ICollection<Teacher> Teacher { get; set; }
}
}
Student.cs
using System;
using System.Collections.Generic;
namespace dbfirst.Models
{
public partial class Student
{
public Student()
{
Studentbook = new HashSet<Studentbook>();
}
public int Id { get; set; }
public string Name { get; set; }
public string Addr { get; set; }
public DateTime? Birth { get; set; }
public byte[] Img { get; set; }
public virtual Studentinfo Studentinfo { get; set; }
public virtual ICollection<Studentbook> Studentbook { get; set; }
}
}
Teacher:
using System;
using System.Collections.Generic;
namespace dbfirst.Models
{
public partial class Teacher
{
public int Id { get; set; }
public string Name { get; set; }
public int Bid { get; set; }
public virtual Book B { get; set; }
}
}
Studentbook.cs:
using System;
using System.Collections.Generic;
namespace dbfirst.Models
{
public partial class Studentbook
{
public int Sid { get; set; }
public int Bookid { get; set; }
public virtual Book Book { get; set; }
public virtual Student S { get; set; }
}
}
Studentinfo.cs:
using System;
using System.Collections.Generic;
namespace dbfirst.Models
{
public partial class Studentinfo
{
public int Sid { get; set; }
public DateTime? Indate { get; set; }
public int? Type { get; set; }
public string Desc { get; set; }
public virtual Student S { get; set; }
}
}
testContext.cs:
using System;
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Metadata;
namespace dbfirst.Models
{
public partial class testContext : DbContext
{
public testContext()
{
}
public testContext(DbContextOptions<testContext> options)
: base(options)
{
}
public virtual DbSet<Book> Book { get; set; }
public virtual DbSet<Student> Student { get; set; }
public virtual DbSet<Studentbook> Studentbook { get; set; }
public virtual DbSet<Studentinfo> Studentinfo { get; set; }
public virtual DbSet<Teacher> Teacher { get; set; }
protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
{
if (!optionsBuilder.IsConfigured)
{
#warning To protect potentially sensitive information in your connection string, you should move it out of source code. See http://go.microsoft.com/fwlink/?LinkId=723263 for guidance on storing connection strings.
optionsBuilder.UseSqlServer("Data Source = .;Initial Catalog = test;User Id = sa;Password = 123456;");
}
}
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
modelBuilder.HasAnnotation("ProductVersion", "2.2.6-servicing-10079");
modelBuilder.Entity<Book>(entity =>
{
entity.ToTable("book");
entity.HasIndex(e => e.Id)
.HasName("UQ__book__3213E83ED78FF78C")
.IsUnique();
entity.Property(e => e.Id)
.HasColumnName("id")
.ValueGeneratedNever();
entity.Property(e => e.Name)
.HasColumnName("name")
.HasMaxLength(50)
.IsUnicode(false);
});
modelBuilder.Entity<Student>(entity =>
{
entity.ToTable("student");
entity.HasIndex(e => e.Id)
.HasName("UQ__student__3213E83E18FC0D17")
.IsUnique();
entity.Property(e => e.Id)
.HasColumnName("id")
.ValueGeneratedNever();
entity.Property(e => e.Addr)
.HasColumnName("addr")
.HasMaxLength(500)
.IsUnicode(false);
entity.Property(e => e.Birth)
.HasColumnName("birth")
.HasColumnType("datetime");
entity.Property(e => e.Img)
.HasColumnName("img")
.HasColumnType("image");
entity.Property(e => e.Name)
.IsRequired()
.HasColumnName("name")
.HasMaxLength(50)
.IsUnicode(false);
});
modelBuilder.Entity<Studentbook>(entity =>
{
entity.HasKey(e => new { e.Sid, e.Bookid })
.HasName("PK_gene_studentbook_sid_bookid");
entity.ToTable("studentbook");
entity.Property(e => e.Sid).HasColumnName("sid");
entity.Property(e => e.Bookid).HasColumnName("bookid");
entity.HasOne(d => d.Book)
.WithMany(p => p.Studentbook)
.HasForeignKey(d => d.Bookid)
.OnDelete(DeleteBehavior.ClientSetNull)
.HasConstraintName("FK_userbook_userbook1");
entity.HasOne(d => d.S)
.WithMany(p => p.Studentbook)
.HasForeignKey(d => d.Sid)
.OnDelete(DeleteBehavior.ClientSetNull)
.HasConstraintName("FK_userbook_userbook");
});
modelBuilder.Entity<Studentinfo>(entity =>
{
entity.HasKey(e => e.Sid)
.HasName("PK_gene_studentinfo_sid");
entity.ToTable("studentinfo");
entity.HasIndex(e => e.Sid)
.HasName("UQ__studenti__DDDFDD370E427379")
.IsUnique();
entity.Property(e => e.Sid)
.HasColumnName("sid")
.ValueGeneratedNever();
entity.Property(e => e.Desc)
.HasColumnName("desc")
.HasMaxLength(500)
.IsUnicode(false);
entity.Property(e => e.Indate)
.HasColumnName("indate")
.HasColumnType("datetime");
entity.Property(e => e.Type).HasColumnName("type");
entity.HasOne(d => d.S)
.WithOne(p => p.Studentinfo)
.HasForeignKey<Studentinfo>(d => d.Sid)
.OnDelete(DeleteBehavior.ClientSetNull)
.HasConstraintName("FK_studentinfo_student");
});
modelBuilder.Entity<Teacher>(entity =>
{
entity.ToTable("teacher");
entity.HasIndex(e => e.Id)
.HasName("UQ__teacher__3213E83EAD9D5139")
.IsUnique();
entity.Property(e => e.Id)
.HasColumnName("id")
.ValueGeneratedNever();
entity.Property(e => e.Bid).HasColumnName("bid");
entity.Property(e => e.Name)
.IsRequired()
.HasColumnName("name")
.HasMaxLength(50)
.IsUnicode(false);
entity.HasOne(d => d.B)
.WithMany(p => p.Teacher)
.HasForeignKey(d => d.Bid)
.OnDelete(DeleteBehavior.ClientSetNull)
.HasConstraintName("FK_teacher_teacher");
});
}
}
}
四、 修改生成的 testContext
,增加日志输出
testContext
修改
testContext
的
OnConfiguring
方法如下:
protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
{
if (!optionsBuilder.IsConfigured)
{
#warning To protect potentially sensitive information in your connection string, you should move it out of source code. See http://go.microsoft.com/fwlink/?LinkId=723263 for guidance on storing connection strings.
optionsBuilder.UseSqlServer("Data Source = .;Initial Catalog = test;User Id = sa;Password = 123456;");
//准备依赖容器
var services = new ServiceCollection();
services.AddLogging(builder =>
{
builder.ClearProviders();
//将日志输出到控制台
builder.AddConsole();
//将日志输出到vs的调试窗口
builder.AddDebug();
});
var provider = services.BuildServiceProvider();
//从容器中拿到日志工厂
var loggerFactory = provider.GetRequiredService<ILoggerFactory>();
//启用efcore的日志记录
optionsBuilder.UseLoggerFactory(loggerFactory);
//使efcore的日志中输出敏感信息(含参数化值)
optionsBuilder.EnableSensitiveDataLogging(true);
}
}
五、编写增删改查代码
只需修改Program.cs即可:
using System;
using System.Text;
using System.Threading.Tasks;
using dbfirst.Models;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Linq.Expressions;
namespace dbfirst
{
class Program
{
static void Main(string[] args)
{
//TestAdd();
//TestQuery();
//TestUpdate();
//TestDelete();
Console.WriteLine("Hello World!");
}
private static void TestDelete()
{
using (testContext db = new testContext())
{
var id = db.Student.Where(i => i.Name == "小明").Select(i => i.Id).FirstOrDefault();
db.Studentbook.RemoveRange(db.Studentbook.Where(i => i.Sid == id));
db.SaveChanges();
}
}
private static void TestUpdate()
{
using (testContext db = new testContext())
{
Book b = db.Book.Where(i => i.Name == "外语").FirstOrDefault();
if (b != null)
{
b.Name = "英语";
}
db.SaveChanges();
}
}
private static void TestQuery()
{
using (testContext db = new testContext())
{
var set = (from stu in db.Student join b in db.Studentbook on stu.Id equals b.Sid join book in db.Book on b.Bookid equals book.Id where stu.Name.Contains("小") select new { StuName = stu.Name, stuId = stu.Id, bookName = book.Name, bookId = book.Id });
var list = set.ToList();
foreach (var i in list)
{
Console.WriteLine(i.bookId + ":" + i.bookName + "," + i.StuName + ":" + i.stuId);
}
}
}
private static void TestAdd()
{
using (testContext db = new testContext())
{
//创建四名学生(小明、小红、小刚、小军)
Student xiaoming = new Student()
{
Id = 1,
Name = "小明",
Birth = DateTime.Parse("1995-02-03"),
Addr = "天民路28号",
Img = Encoding.UTF8.GetBytes("哈哈 this is a 测试")
};
Student xiaohong = new Student()
{
Id = 2,
Name = "小红",
Birth = DateTime.Parse("1998-07-03"),
Addr = "顺丰路28号",
Img = Encoding.UTF8.GetBytes("哈哈 this is a 测试")
};
Student xiaogang = new Student()
{
Id = 3,
Name = "小刚",
Birth = DateTime.Parse("1994-07-03"),
Addr = "江山28号",
Img = Encoding.UTF8.GetBytes("哈哈 this is a 测试")
};
Student xiaojun = new Student()
{
Id = 4,
Name = "小军",
Birth = DateTime.Parse("1995-07-03"),
Addr = "江山29号",
Img = Encoding.UTF8.GetBytes("哈哈 this is a 测试")
};
//创建三门课(语文、数学、外语)
Book yuwen = new Book()
{
Id = 1,
Name = "语文"
};
Book shuxue = new Book()
{
Id = 2,
Name = "数学"
};
Book waiyu = new Book()
{
Id = 3,
Name = "外语"
};
//创建三个老师分别教三门课
Teacher yuwenlaoshi = new Teacher()
{
Id = 1,
Name = "语文老师",
Bid = yuwen.Id
};
Teacher shuxuelaoshi = new Teacher()
{
Id = 2,
Name = "数学老师",
Bid = shuxue.Id
};
Teacher waiyulaoshi = new Teacher()
{
Id = 3,
Name = "外语老师",
Bid = waiyu.Id
};
//给三个学生都选择语数外三门课
Studentbook xiaohongyuwen = new Studentbook()
{
Bookid = yuwen.Id,
Sid = xiaohong.Id
};
Studentbook xiaohongshuxue = new Studentbook()
{
Bookid = shuxue.Id,
Sid = xiaohong.Id
};
Studentbook xiaohongwaiyu = new Studentbook()
{
Bookid = waiyu.Id,
Sid = xiaohong.Id
};
Studentbook xiaomingyuwen = new Studentbook()
{
Bookid = yuwen.Id,
Sid = xiaoming.Id
};
Studentbook xiaomingshuxue = new Studentbook()
{
Bookid = shuxue.Id,
Sid = xiaoming.Id
};
Studentbook xiaomingwaiyu = new Studentbook()
{
Bookid = waiyu.Id,
Sid = xiaoming.Id
};
Studentbook xiaogangyuwen = new Studentbook()
{
Bookid = yuwen.Id,
Sid = xiaogang.Id
};
Studentbook xiaogangshuxue = new Studentbook()
{
Bookid = shuxue.Id,
Sid = xiaogang.Id
};
Studentbook xiaogangwaiyu = new Studentbook()
{
Bookid = waiyu.Id,
Sid = xiaogang.Id
};
Studentbook xiaojunyuwen = new Studentbook()
{
Bookid = yuwen.Id,
Sid = xiaojun.Id
};
Studentbook xiaojunshuxue = new Studentbook()
{
Bookid = shuxue.Id,
Sid = xiaojun.Id
};
Studentbook xiaojunwaiyu = new Studentbook()
{
Bookid = waiyu.Id,
Sid = xiaojun.Id
};
//给四名同学添加扩展信息
Studentinfo xiaominginfo = new Studentinfo()
{
Sid = xiaoming.Id,
Indate = DateTime.Now,
Type = 1,
Desc = "一段描述"
};
Studentinfo xiaojuninfo = new Studentinfo()
{
Sid = xiaojun.Id,
Indate = DateTime.Now,
Type = 1,
Desc = "一段描述"
};
Studentinfo xiaohonginfo = new Studentinfo()
{
Sid = xiaohong.Id,
Indate = DateTime.Now,
Type = 1,
Desc = "一段描述"
};
Studentinfo xiaoganginfo = new Studentinfo()
{
Sid = xiaogang.Id,
Indate = DateTime.Now,
Type = 1,
Desc = "一段描述"
};
db.AddRange(xiaoming, xiaogang, xiaojun, xiaohong);
db.AddRange(yuwen, waiyu, shuxue);
db.AddRange(yuwenlaoshi, shuxuelaoshi, waiyulaoshi);
db.AddRange(xiaominginfo, xiaoganginfo, xiaojuninfo, xiaohonginfo);
db.AddRange(xiaomingyuwen, xiaomingshuxue, xiaomingwaiyu);
db.AddRange(xiaohongyuwen, xiaohongshuxue, xiaohongwaiyu);
db.AddRange(xiaogangyuwen, xiaogangshuxue, xiaogangwaiyu);
db.AddRange(xiaojunyuwen, xiaojunshuxue, xiaojunwaiyu);
db.SaveChanges();
}
}
}
}
六、测试效果
先运行“TestAdd”添加数据,观察如下:
控制台日志输出如下:
接下来依次运行:
TestQuery
、
TestUpdate
、
TestDelete
即可。
七、codefirst模式
在dbfirst实验的基础上,完成codefirst实验,修改
codefirst
工程:
- 添加nuget包(和dbfirst一样即可)
- 将
中的代码拷贝到dbfirst工程
中,并将命名空间修改为codefirst工程
codefirst
- 修改数据库为
(在test2
中修改)testContext.cs
最终效果如下:
.netcore入门4:Microsoft.EntityFrameworkCore操作笔记一、准备数据库二、准备工程三、从数据库生成模型代码四、 修改生成的testContext,增加日志输出五、编写增删改查代码六、测试效果七、codefirst模式八、说一下codefirst模式和dbfirst模式 .netcore入门4:Microsoft.EntityFrameworkCore操作笔记一、准备数据库二、准备工程三、从数据库生成模型代码四、 修改生成的testContext,增加日志输出五、编写增删改查代码六、测试效果七、codefirst模式八、说一下codefirst模式和dbfirst模式 - 将
设为启动程序codefirst
- 在包管理平台中执行
命令,如下所示:Add-Migration init
.netcore入门4:Microsoft.EntityFrameworkCore操作笔记一、准备数据库二、准备工程三、从数据库生成模型代码四、 修改生成的testContext,增加日志输出五、编写增删改查代码六、测试效果七、codefirst模式八、说一下codefirst模式和dbfirst模式 - 可看到生成的迁移类和快照
- 在包管理平台中执行
命令,如下所示:Update-Database
.netcore入门4:Microsoft.EntityFrameworkCore操作笔记一、准备数据库二、准备工程三、从数据库生成模型代码四、 修改生成的testContext,增加日志输出五、编写增删改查代码六、测试效果七、codefirst模式八、说一下codefirst模式和dbfirst模式 - 观察数据库test2:
.netcore入门4:Microsoft.EntityFrameworkCore操作笔记一、准备数据库二、准备工程三、从数据库生成模型代码四、 修改生成的testContext,增加日志输出五、编写增删改查代码六、测试效果七、codefirst模式八、说一下codefirst模式和dbfirst模式
可以看到,自动建了数据库test2并且建好了表结构
- 拷贝dbfirst的Program.cs的代码到codefirst中去(注意:修改命名空间),依次执行测试代码即可。
八、说一下codefirst模式和dbfirst模式
首先说明dbfirst就是先建好数据库,然后使用命令
Scaffold-DbContext "Data Source = .;Initial Catalog = test;User Id = sa;Password = 123456;" Microsoft.EntityFrameworkCore.SqlServer -OutputDir Models
将指定的数据库中所有表生成代码到指定的工程目录中去,这就结束了。
再看一下codefirst模式,在这种模式下最后不要在数据库客户端修改数据库的结构,如果想修改数据库结构,就先改代码,然后让EntityFrameworkCore工具自动去执行修改数据库结构。
codefirst一般操作流程如下:
- 工程中建好实体model和dbcontext(注意工程需要是可执行程序)
- 在包管理控制台中使用
命令生成用来执行迁移操作的代码(init是每次迁移的一个标识,可自定义)Add-Migration init
- 如果此时数据库结构有改动需要再次修改工程的实体model和dbcontext,那么你可以执行
命令直接将最近的依次迁移代码删除掉Remove-Migration
- 确认工程的实体model和dbcontext没问题并且生成的迁移代码没有问题,那么可以执行命令
将迁移代码应用到数据库中,此时codefirst也就完成了。Update-Database
codefirst涉及到的命令说明:
- Add-Migration [自定义标识] ,示例:
Add-Migration init
(注:这个过程不需要和数据库交互)
初次使用将根据DbContext找到对应的实体类,然后根据实体类生成“20190910082556_init”迁移类,这个类里面记录的是要创建的表和字段,并且生成此时这个表的快照(根据实体类生成)
非初次运行这个命令的时候,将对比当前的实体类和这个表的快照,然后根据对比的结果生成迁移类并更新快照
-
Update-Database
首先连接数据库获取数据库已经迁移过的版本号(表:__EFMigrationsHistory中记录历史更新记录),然后对比当前工程下的迁移代码的版本号,如果发现还有未执行的迁移代码那么就执行迁移代码,如果没有的话就不执行
-
Remove-Migration
首先连接数据库获取数据库已经迁移过的版本号,然后对比当前工程最新的迁移类的版本号,如果数据库中没有记录这个版本号表示迁移类还未执行,那么直接删除掉这个迁移类,并更新快照,如果发现已经执行了这个迁移类那么就报错提示“已经更新到数据库了”
-
Get-DbContext
获取当前工程的上下文环境
-
Script-Migration
将当前的迁移代码翻译成sql脚本