0%

Entity Framework Core1——基础使用

EntityFrameworkCore

  • Entity Framework (EF) Core 是轻量化、可扩展、开源和跨平台版的常用 Entity Framework 数据访问技术。

  • EF Core 可用作对象关系映射程序 (O/RM),这可以实现以下两点:

  • 使 .NET 开发人员能够使用 .NET 对象处理数据库。
  • 无需再像通常那样编写大部分数据访问代码。

使用EFCore的准备工作

创建项目

  • 创建两个类库Linq.Domain、Linq.Data和一个控制台项目Linq.App

创建实体类

  • 然后再Linq.Domain中添加Entity实体,在这里我们创建Club、League和Player,分别是俱乐部、联队和足球运动员,其中联赛和俱乐部是一对多关系,俱乐部和运动员是一对多关系、
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
//Club
public class Club
{
public Club()
{
Players = new List<Player>();
}
public int Id { get; set; }
public string Name { get; set; }
public string City { get; set; }
public DateTime DateOfEstablishment { get; set; }
public string History { get; set; }
//导航属性
public League League { get; set; }
//导航属性
public List<Player> Players { get; set; }
}
//League
public class League
{
public int Id { get; set; }
public string Name { get; set; }
public string Country { get; set; }
}
//Player
public class Player
{
public int Id { get; set; }
public string Name { get; set; }
public DateTime DateOfBirth { get; set; }
}

添加依赖

  • 在Linq.Data的nuget中添加EFCore对SqlServer的支持和添加Linq.Domain的引用
1
2
3
4
5
6
<ItemGroup>
<PackageReference Include="Microsoft.EntityFrameworkCore.SqlServer" Version="3.1.8" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\Linq.Domain\Linq.Domain.csproj" />
</ItemGroup>
  • 在Linq.App中添加Linq.Data的引用
1
2
3
4
<ItemGroup>
<ProjectReference Include="..\Linq.Data\Linq.Data.csproj" />
<ProjectReference Include="..\Linq.Domain\Linq.Domain.csproj" />
</ItemGroup>

DbContext

  • DbContext是EFCore操作数据库的上下文类,使用它可以对数据库的连接进行一些配置、或对表中属性添加约束、或添加种子数据等等。
  • DbContext中对Context进行配置的方法是OnConfiguring该方法定义在DbContext这个类中
  • 现在,创建一个LinqContext类:这个类必须继承于DbContext,且要将创建的数据库表以DbSet类型定义在Context中,后面可以使用这些DbSet对数据库进行访问。
1
2
3
4
5
6
7
8
9
10
11
12
13
public class LinqDbContext: DbContext
{
//该方法可以对DbContext进行一些配置,在这里使用了本地的SqlServer,并指定了连接字符串
protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
{
optionsBuilder.UseSqlServer(
"Data Source=(localdb)\\MSSQLLocalDB; Initial Catalog=LinqDb");
}

public DbSet<League> Leagues { get; set; }
public DbSet<Club> Clubs { get; set; }
public DbSet<Player> Players { get; set; }
}

创建数据库

  • 做好准备工作后,创建数据库只需要以下三步

    1. 定义Model,这些Model在准备工作已经定义好了,他们就是对应于数据库中的数据库表。
    2. 创建迁移文件(Migration)。
    3. 使用迁移文件生成脚本或将其应用到数据库。

    Snipaste_2020-10-06_17-17-29

添加依赖

  • 迁移需要用到Migration命令,Migration命令需要用到两个库(如果使用vscode,只需要安装Design库,vs的话只需要安装Tools库,因为Tools库已经依赖了Design库):

Microsoft.EntityFrameworkCore.Tools:该库添加了对包管理控制台的迁移命令的支持

Microsoft.EntityFrameworkCore.Design:该库添加了对迁移操作的核心支持

  • 要想生成DbContext对应的迁移文件,必须要有一个可执行的文件,所以你可以使用控制台项目或者Web项目等可执行的项目来生成迁移文件,这里使用的是控制台(Linq.App)。

  • 安装完Tools库后就可以在程序包管理器控制台上输入EntityFrameworkCore的命令,在这里输入get-help entityframework就可以查看有哪些命令

    Snipaste_2020-10-06_19-29-44

  • 在这里需要注意的是,在输入命令之前需要把默认项目改成安装了Tools库的项目,而且要在执行项目中安装Design库才能迁移成功。

添加迁移

  • 执行Add-Migration [迁移名称]就可以进行迁移

    Snipaste_2020-10-06_19-37-03

  • 执行完命令后就会自动生成两个文件:一个是迁移文件,另一个是快照文件

    Snipaste_2020-10-06_19-40-05

  • 迁移文件:每次迁移都会生成一个迁移文件,它会记录每一次迁移的所有改动。它的名字就是时间戳+迁移名称。

  • 迁移类:迁移类会继承于Migration这个基类,它里面有两个方法:

    1. Up:该方法定义了本次迁移对数据库的修改
    2. Down:该方法定义了当修改有一些问题时进行的回滚。
1
2
3
4
5
public partial class Initial : Migration
{
protected override void Up(MigrationBuilder migrationBuilder){...}
protected override void Down(MigrationBuilder migrationBuilder){...}
}
  • 快照文件:EFCore会使用这个文件来追踪当前所有Model的状态,比如我们修改了一个Model,EFCore就会在添加迁移时根据当前Model的状态和快照中Model的状态进行对比,就可以知道下一步该如何操作。该文件不应该去修改它。

生成脚本

  • 执行script-migration可以生成本次迁移的Sql脚本。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
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 [Leagues] (
[Id] int NOT NULL IDENTITY,
[Name] nvarchar(max) NULL,
[Country] nvarchar(max) NULL,
CONSTRAINT [PK_Leagues] PRIMARY KEY ([Id])
);

GO

CREATE TABLE [Clubs] (
[Id] int NOT NULL IDENTITY,
[Name] nvarchar(max) NULL,
[City] nvarchar(max) NULL,
[DateOfEstablishment] datetime2 NOT NULL,
[History] nvarchar(max) NULL,
[LeagueId] int NULL,
CONSTRAINT [PK_Clubs] PRIMARY KEY ([Id]),
CONSTRAINT [FK_Clubs_Leagues_LeagueId] FOREIGN KEY ([LeagueId]) REFERENCES [Leagues] ([Id]) ON DELETE NO ACTION
);

GO

CREATE TABLE [Players] (
[Id] int NOT NULL IDENTITY,
[Name] nvarchar(max) NULL,
[DateOfBirth] datetime2 NOT NULL,
[ClubId] int NULL,
CONSTRAINT [PK_Players] PRIMARY KEY ([Id]),
CONSTRAINT [FK_Players_Clubs_ClubId] FOREIGN KEY ([ClubId]) REFERENCES [Clubs] ([Id]) ON DELETE NO ACTION
);

GO

CREATE INDEX [IX_Clubs_LeagueId] ON [Clubs] ([LeagueId]);

GO

CREATE INDEX [IX_Players_ClubId] ON [Players] ([ClubId]);

GO

INSERT INTO [__EFMigrationsHistory] ([MigrationId], [ProductVersion])
VALUES (N'20201006113413_Initial', N'3.1.8');

GO

更新数据库

  • 生成脚本一般是在生产环境中使用的,而在开发环境中可以执行update-database -verbose来将迁移应用到数据库,这将会生成如下数据库

    Snipaste_2020-10-06_20-08-11

  • 其中的History是迁移记录表


学习资料:B站杨旭

-------------本文结束感谢您的阅读-------------