第 5 章 使用 Entity Framework Core
5.1 Entity Framework Core
EF Core 是微软推出的 ORM 框架,一种为了解决高级编程语言中的对象和关系型数据库之间映射关系的技术,它能够将程序中的对象自动持久化到关系型数据库中,并能够将数据库中的数据信息自动映射到编程语言中的对象
EF Core 的另一个特点是支持 LINQ,通过 LINQ,我们能够像操作 .NET 集合对象中的数据一样来操作数据库中存储的数据
5.2 使用 EF Core
EF Core 有两种使用方式:
- 代码优先:根据先创建好的实体类来创建数据库和表
- 数据库优先:根据先创建好的数据库以及其中的数据表来生成与之匹配的实体类
创建一个新项目时,通常建议使用“代码优先”的方法,如果使用“数据库优先”,可以通过以下命令生成数据库对应代码
代码语言:javascript复制Scaffold-DbContext
代码优先,创建实体类
代码语言:javascript复制namespace Library.API.Entities
{
public class Author
{
[Key, DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public Guid Id { get; set; }
[Required]
[MaxLength(20)]
public string Name { get; set; }
[Required]
public DateTimeOffset BirthData { get; set; }
[Required]
[MaxLength(40)]
public string BirthPlace { get; set; }
[Required]
[EmailAddress]
public string Email { get; set; }
public ICollection<Book> Books { get; set; } = new List<Book>();
}
}
namespace Library.API.Entities
{
public class Book
{
[Key]
public Guid Id { get; set; }
[Required]
[MaxLength(100)]
public string Title { get; set; }
[MaxLength(500)]
public string Description { get; set; }
public int Pages { get; set; }
[ForeignKey("AuthorId")]
public Author Author { get; set; }
public Guid AuthorId { get; set; }
}
}
创建 DbContext 类
代码语言:javascript复制using Microsoft.EntityFrameworkCore;
namespace Library.API.Entities
{
public class LibraryDbContext : DbContext
{
public DbSet<Author> Authors { get; set; }
public DbSet<Book> Books { get; set; }
/// <summary>
/// 添加构造函数之后才可以注入容器
/// </summary>
/// <param name="options"></param>
public LibraryDbContext(DbContextOptions<LibraryDbContext> options) : base(options)
{
}
}
}
在 ConfigureServices 方法中将 LibraryDbContext 添加到容器中
代码语言:javascript复制services.AddDbContext<LibraryDbContext>(option =>
{
option.UseSqlServer(Configuration.GetConnectionString("DefaultConnection"));
});
使用 UseSqlServer 之前需要添加引用
代码语言:javascript复制Install-Package Microsoft.EntityFrameworkCore.SqlServer
在 appsettings.json 文件的一级节点下增加配置
代码语言:javascript复制"ConnectionStrings": {
"DefaultConnection": "Server=(localdb)\mssqllocaldb;Database=LibraryAPI;Trusted_Connection=True;MultipleActiveResultSets=true"
}
添加引用
代码语言:javascript复制Install-Package Microsoft.EntityFrameworkCore.Design
添加迁移与创建数据库
代码语言:javascript复制dotnet ef migrations add InitialCreation
上述命令成功执行之后项目中多了一个文件夹 Migrations,包含本次迁移
更新一波 EF Core tools
代码语言:javascript复制dotnet tool update --global dotnet-ef
接着将迁移应用到数据库中
代码语言:javascript复制dotnet ef database update
命令执行成功之后,数据库就创建成功了
添加测试数据,在 LibraryDbContext 中重载 OnModelCreating 方法
代码语言:javascript复制protected override void OnModelCreating(ModelBuilder modelBuilder)
{
base.OnModelCreating(modelBuilder);
modelBuilder.Entity<Author>().HasData(
new Author
{
Id = Guid.NewGuid(),
Name = "Author",
BirthData = new DateTimeOffset(new DateTime(1960, 11, 18)),
BirthPlace = "广东汕头",
Email = "author@xxx.com"
});
}
要让这些数据添加到数据库中,还应创建一个迁移
代码语言:javascript复制dotnet ef migrations add SeedData
执行成功之后,自动生成迁移文件,以 _SeedData 结尾,在 Up 方法中向数据库添加数据
代码语言:javascript复制namespace Library.API.Migrations
{
public partial class SeedData : Migration
{
protected override void Up(MigrationBuilder migrationBuilder)
{
migrationBuilder.InsertData(
table: "Authors",
columns: new[] { "Id", "BirthData", "BirthPlace", "Email", "Name" },
values: new object[] { new Guid("2d149469-c630-41fa-98f1-226f50534fbc"), new DateTimeOffset(new DateTime(1960, 11, 18, 0, 0, 0, 0, DateTimeKind.Unspecified), new TimeSpan(0, 8, 0, 0, 0)), "广东汕头", "author@xxx.com", "Author" });
}
protected override void Down(MigrationBuilder migrationBuilder)
{
migrationBuilder.DeleteData(
table: "Authors",
keyColumn: "Id",
keyValue: new Guid("2d149469-c630-41fa-98f1-226f50534fbc"));
}
}
}
接着将迁移应用到数据库中
代码语言:javascript复制dotnet ef database update
命令执行成功之后,可以看到新添加的数据
如果要删除测试数据,可以注释添加测试数据的代码,并添加一个迁移即可
如果添加数据是最近的一次迁移操作,并且还未执行数据库更新命令,可以直接通过以下命令删除该迁移
代码语言:javascript复制dotnet ef migrations remove