EF Core 是现有EF库的修改版本,具有可扩展的,轻量级的和跨平台的支持。它支持关系型数据库和非关系型数据库。还支持"代码优先"或"数据库优先"方法作为编程模型。
代码优先(Code first)是一种技术,可以帮助我们通过代码来创建数据库,迁移和维护数据库及其表。也就意味着我们可以通过.NET代码直接维护数据库及其对应的表。当尚未准备好数据库并且想要在新项目中创建数据库并直接通过代码维护数据库时,这将是个很好的选择。
本文将帮助大家了解什么是“代码优先”的方法,以及如何使用Entity Framework Core 迁移(Migration)机制在ASP.NET Core 应用程序中实现它。Migration始终可以帮助我们创建,更新数据库并将其与模型类同步。接下来将演示创建一个新的应用程序。
打开Visual Studio 2019并创建一个新的ASP.NET Core API应用程序。在Visual Studio 2019中创建ASP.NET Core API应用程序时,可以按照以下步骤操作。
您可能会喜欢以下更多文章:
现在我们已经准备好项目。可以使用F5运行应用程序,如果运行正常那么我们可以继续往下走。
我们需要访问Sqlserver数据库,所以通过NuGet软件包管理器中来安装Microsoft.EntityFrameworkCore.SqlServer的包,这个包将提供用于与SQL Server数据库连接对EF Core进行CRUD操作的类。
第二个必需的NuGet软件包是Microsoft.EntityFrameworkCore.Tools,它将帮助我们处理与数据库相关的活动,例如Microsoft.EntityFrameworkCore.Tools提供的add-migration命令用于生成迁移脚本文件,update-database命令根据脚本文件生成表,以及获取dbcontext,更新数据库等。
到目前为止,我们已经创建了一个Asp.Net Core API应用程序并安装了一些必需的Entity Framework Core程序包,这些程序包是Code First迁移所必需的,或者可以说,这些将帮助我们使用Entity Framework Core功能来与SQL Server一起使用。
准备工作做好后,接下来,在项目的根目录创建一个文件夹名称为“dbContext”,并在其中创建一个Model类“ Employee”,并具有以下属性,创建的实体是具有DB属性的常规C#类,实体不是"DTO"对象,因为它是为数据库交互而设计的。我们使用的是代码优先的方法,因此这些实体类是数据库创建的输入:
- namespace EFCoreMigration.dbContext
- {
- public class Employee
- {
- public int EmployeeId { get; set; }
- public string Name { get; set; }
- public string Address { get; set; }
- public string CompanyName { get; set; }
- public string Email { get; set; }
- public int age { get; set; }
- }
- }
我们需要将"DbContext"文件添加到我们的应用程序中,根据Microsoft的定义,"DbContext"实例代表与数据库的会话,可用于查询和保存实体的实例。"DbContext"是"工作单元"和"存储库模式"的组合。在dbContext文件夹中创建另一个派生自"DbContext"基类的类文件“EmployeeDbContext”,该基类是"Microsoft.EntityFrameworkCore"的一部分,该类继承DbContext类。此类将包含负责在数据库中创建表的所有模型信息。这个类也称为上下文类,这个上下文类通常包括模型中每个实体的DaSet<TEntity>属性,在这里,我们将Employee类定义为DbSet。
- namespace EFCoreMigration.dbContext
- {
- public class EmployeeDbContext : DbContext
- {
- public EmployeeDbContext(DbContextOptions options) : base(options)
- {
- }
- DbSet<Employee> Employees { get; set; }
- }
- }
要在数据库中创建这些表,需要定义连接字符串,并在其中定义服务器和数据库名称。这里我们不使用SQL Windows身份验证,但是您可以使用混合身份验证并将用户名和密码与连接字符串一起传递。在appsetting.json文件中写入连接字符串如下所示:
要使用以上连接字符串,需要更改Startup.cs类中的ConfigureServices方法。
- public void ConfigureServices(IServiceCollection services)
- {
- services.AddControllers();
- services.AddDbContext<EmployeeDbContext>(item => item.UseSqlServer(Configuration.GetConnectionString("sqlconn")));
- }
到目前为止,我们已经完成了大部分工作,例如创建项目,安装NuGet包,创建Model类以及设置连接字符串。下面可以使用Entity Framework Core Migrations生成数据库和表了。
从VS的菜单栏"工具"选项中打开"程序包管理器(Package Manager)控制台",然后选择要为其生成迁移代码的默认项目,这里选择的项目是我们的EFCoreMigration。
为了创建迁移代码文件,需要使用“ add-migration MigrationName”命令。这里我们就把MigrationName的文件名称改为MigrationDB,在Package Manager控制台中,只需键入“ add-migration MigrationDB”命令,然后按Enter。
成功执行add-migration命令后,它将在项目中创建一个名为“ Migrations”的文件夹,并使用在执行带有迁移脚本文件名称的add migration命令时提供的名称MigrationDB创建该类。在这个MigrationDB类中可以看到基于模型(员工)的表结构,该表结构已准备好生成数据库。
- using Microsoft.EntityFrameworkCore.Migrations;
-
- namespace EFCoreMigration.Migrations
- {
- public partial class MigrationDB : Migration
- {
- protected override void Up(MigrationBuilder migrationBuilder)
- {
- migrationBuilder.CreateTable(
- name: "Employees",
- columns: table => new
- {
- EmployeeId = table.Column<int>(nullable: false)
- .Annotation("SqlServer:Identity", "1, 1"),
- Name = table.Column<string>(nullable: true),
- Address = table.Column<string>(nullable: true),
- CompanyName = table.Column<string>(nullable: true),
- Email = table.Column<string>(nullable: true),
- age = table.Column<int>(nullable: false)
- },
- constraints: table =>
- {
- table.PrimaryKey("PK_Employees", x => x.EmployeeId);
- });
- }
-
- protected override void Down(MigrationBuilder migrationBuilder)
- {
- migrationBuilder.DropTable(
- name: "Employees");
- }
- }
- }
我们仅创建了负责创建数据库及其表的迁移脚本。但是我们还没有创建实际的数据库和表。这就需要执行生成好的迁移脚本,用于生成实际的数据库和表。执行迁移脚本的命令用“ update-database”。
目前,我们只有一个迁移脚本,所以不需要提供迁移名称,直接用update-database命令。如果我们有多个迁移脚本,则必须提供名称以及命令update-database MigrationDB,如下所示:
更新数据库迁移名称
现在,修改Employee模型,并添加一个新的属性字段,如薪水Salary,其类型为float。
- public class Employee
- {
- public int EmployeeId { get; set; }
- public string Name { get; set; }
- public string Address { get; set; }
- public string CompanyName { get; set; }
- public string Email { get; set; }
- public int age { get; set; }
- public float Salary { get; set; }
- }
转到程序包管理器控制台并运行以下命令以添加迁移文件,这一次,我们将迁移的名称指定为“ addsalary”。
add-migration addsalary
一旦上述命令执行完成,它将为迁移名称创建一个新类,如下所示。在这里我们可以看到,迁移构建器具有用于添加新列作为薪水的配置。
- using Microsoft.EntityFrameworkCore.Migrations;
-
- namespace EFCoreMigration.Migrations
- {
- public partial class addsalary : Migration
- {
- protected override void Up(MigrationBuilder migrationBuilder)
- {
- migrationBuilder.AddColumn<float>(
- name: "Salary",
- table: "Employees",
- nullable: false,
- defaultValue: 0f);
- }
-
- protected override void Down(MigrationBuilder migrationBuilder)
- {
- migrationBuilder.DropColumn(
- name: "Salary",
- table: "Employees");
- }
- }
- }
为了使用新列Salary作为薪水来更新数据库中的表,需要在程序包管理器控制台运行以下命令来更新数据库:
update-database addsalary
上述更新数据库命令一旦成功执行,只需检查数据库表即可。将会发现新列Salary已添加到"Employees"表中。
现在,看看如何将一些虚拟数据植入表中。进入EmployeeDbContext类并覆盖DbContext方法“ OnModelCreating”。借助ModelBuilder,我们可以为Employees表添加一些虚拟数据,如下所示:
- namespace EFCoreMigration.dbContext
- {
- public class EmployeeDbContext : DbContext
- {
- public EmployeeDbContext(DbContextOptions options) : base(options)
- {
- }
- DbSet<Employee> Employees { get; set; }
- protected override void OnModelCreating(ModelBuilder modelBuilder)
- {
- modelBuilder.Entity<Employee>().HasData(
- new Employee() { EmployeeId = 1, Name = "Robin", Address = "上海", CompanyName = "腾讯", Email = "Robin@tengxun.com", age=22, Salary = 300000 },
- new Employee() { EmployeeId = 2, Name = "Susan", Address = "北京", CompanyName = "头条", Email = "Susan@toutiao.com", age=20, Salary = 250000 });
- }
- }
- }
使用以下命令将其添加到迁移中:
add-migration employeedata
上面的命令成功执行后,可以看到将使用插入数据配置生成以下employeedata类。在这里,我们定义要在其中添加数据的表名,列及其各自的值。
- using Microsoft.EntityFrameworkCore.Migrations;
-
- namespace EFCoreMigration.Migrations
- {
- public partial class employeedata : Migration
- {
- protected override void Up(MigrationBuilder migrationBuilder)
- {
- migrationBuilder.InsertData(
- table: "Employees",
- columns: new[] { "EmployeeId", "Address", "CompanyName", "Email", "Name", "Salary", "age" },
- values: new object[] { 1, "上海", "腾讯", "Robin@tengxun.com", "Robin", 300000f, 22 });
-
- migrationBuilder.InsertData(
- table: "Employees",
- columns: new[] { "EmployeeId", "Address", "CompanyName", "Email", "Name", "Salary", "age" },
- values: new object[] { 2, "北京", "头条", "Susan@toutiao.com", "Susan", 250000f, 20 });
- }
-
- protected override void Down(MigrationBuilder migrationBuilder)
- {
- migrationBuilder.DeleteData(
- table: "Employees",
- keyColumn: "EmployeeId",
- keyValue: 1);
-
- migrationBuilder.DeleteData(
- table: "Employees",
- keyColumn: "EmployeeId",
- keyValue: 2);
- }
- }
- }
执行以下命令使用生成的迁移类更新数据库:
update-database employeedata
以上命令在Package Manager控制台中成功执行,只需到数据库管理工具并刷新表即可。会发现我们在迁移中定义的数据已更新到表中。
项目结构图如下:
结论
今天,学习了如何使用EF Core迁移机制在Asp.Net Core API项目中实现代码优先的方法。
希望这篇文章对大家有所帮助。请使用评论添加你的反馈意见,这有助于我提高自己的下一篇文章。如果有任何疑问,请在评论部分提出你的疑问,后续会持续更新博客,期望大家关注,共同进步,谢谢。