Entity Framework Core 中的约定
了解 EF Core 的默认约定。
概述
EF Core 在构建模型时遵循一组规则,这些规则统称为约定。在本课程中,我们将回顾 EF Core 默认遵循的约定。
从现在起,我们的演示将采用代码优先(Code First)工作流。请记住,代码优先工作流使用迁移(migrations)。迁移代表某一时刻模型的快照。通过查看迁移,我们可以了解所指定的配置。
注意: 本课程中的命令会生成代码和文件。通过终端,我们可以使用 Linux 命令如 ls 查看文件和目录列表,cd 切换目录,cat 查看文件内容来导航到这些文件。同时,还提供了一个 SPA 小部件,用于显示包含生成文件的更新项目。此外,请注意 EF Core 在生成的文件名中使用时间戳。我们用
xxx表示这些文件名。
默认约定
为了说明默认约定,我们将使用下面这个 C# 控制台应用程序项目:
No configuration found for ID: 16ead7859f089ec7ed2e10282cf24afdd37695a20a87980124efc406886352f2
点击上方 SPA 小部件的“运行”按钮添加一个迁移,然后在终端中执行以下命令:
1dotnet ef migrations add DefaultConventions
接下来,使用以下命令更新数据库:
1dotnet ef database update
数据库更新后,我们的项目已更新如下:
No configuration found for ID: b5ffc7a4540aefcb907132ab743b7d3ef47a36e46f4b872f674b5cce854f57ca
请注意更新项目中“展示默认约定的更新项目”部分的变化。
项目中有一个名为 ArtistsContext 的上下文类,位于 Data 目录下。同时,Entities 目录中包含以下类型:
Employee:表示音乐艺术家的姓名和年龄。Album:表示音乐艺术家发行的专辑。Promoter:表示与音乐艺术家合作策划活动的工作人员。
将类型包含进模型
EF Core 根据以下标准将类型包含进模型:
-
在上下文中以
DbSet<TEntity>属性暴露的类型会被包含为实体。Employee实体被包含进模型,因为DbSet<TEntity>属性在ArtistsContext.cs文件的第 12 行暴露了它。 -
在上下文类的
OnModelCreating方法中指定的类型会被包含进模型。EF Core 在ArtistsContext.cs文件的第 16 行包含了Promoter实体。 -
通过递归探索其他已发现实体类型的导航属性找到的类型也会被包含进模型。由于存在
Employee.Albums导航属性,EF Core 将Album添加到了模型中。
因此,更新项目中 xxx_DefaultConventions.cs 迁移文件的第 11 至 58 行包含对发现实体的 CreateTable 语句。数据库更新后,我们得到以下表:
EmployeesAlbumPromoter
创建列
-
EF Core 为实体类型的每个标量属性创建列,列名与属性名相同。
-
xxx_DefaultConventions.cs文件的第 15–19 行、第 30–33 行和第 44–48 行分别在创建Employees、Promoter和Album表时,使用属性名作为列名。
列的数据类型
列的数据类型取决于特定数据库提供程序对相应 C# 数据类型的映射。本演示使用 SQLite,因此应用以下映射:
xxx_DefaultConventions.cs文件的第 15 和 19 行将longC# 数据类型映射为Employees表中的INTEGER。xxx_DefaultConventions.cs文件的第 17–18 行将stringC# 数据类型映射为Employees表中的TEXT。
其他实体也应用类似的映射。
创建可空列
EF Core 为所有引用类型和可空值类型属性创建可空列:
xxx_DefaultConventions.cs文件的第 17–18 行将Employees表的FirstName和LastName列设置为可空。Promoter和Album表也执行类似操作。
创建非空列
EF Core 为所有主键和值类型属性创建非空列:
xxx_DefaultConventions.cs文件的第 15 和 19 行将Employees表的Id和Age列设置为非空。Promoter和Album表也执行类似操作。
主键
EF Core 使用名为 Id 或 <实体类型名称>Id(不区分大小写)的实体属性来配置主键列。在关系型数据库中,主键约束的名称为 PK_<实体类型名称>:
-
xxx_DefaultConventions.cs文件的第 23 行使用Employee的Id属性配置Employees表的主键。 -
类似配置在
xxx_DefaultConventions.cs文件的第 37 和 52 行分别应用于Promoter和Album表。
外键
EF Core 使用外键来表示关系。EF Core 为实体中的每个引用导航属性配置外键列。如果属性符合以下任一模式,则进行配置:
<导航属性名称>Id<导航属性名称><主键属性名称><主实体名称><主键属性名称><主实体名称>Id
xxx_DefaultConventions.cs 文件的第 53–57 行将 Album 表中的 EmployeeId 配置为外键。在此例中,EmployeeId 是一个影子外键。
影子属性
影子属性 是未在实体类型中定义,但在 EF Core 模型中为该实体类型定义的属性。当 EF Core 发现两个实体之间的关系,但未在依赖实体中找到外键属性时,就会引入影子属性。其名称为 <导航属性名称><主键属性名称>。在此例中,由于通过 Album.Employee 引用导航属性发现了关系,EF Core 引入了 EmployeeId。EF Core 将该属性配置为影子外键。
索引
索引可以提高基于某一列(或一组列)的查找效率。根据约定,EF Core 会在用作外键的每个属性(或属性组)上创建索引。关系型数据库中创建的索引命名为 IX_<类型名称>_<属性名称>。xxx_DefaultConventions.cs 文件的第 60–63 行基于外键 EmployeeId 创建了一个名为 IX_Album_EmployeeId 的索引。