Entity Framework Core in Action
Entityframework Core in action是 Jon P smith
所著的关于Entityframework Core 书籍。原版地址. 是除了官方文档外另一个学习EF Core的不错途径, 书中由浅入深的讲解的EF Core的相关知识。因为没有中文版,所以本人对其进行翻译。 预计每两天一篇更新 PS: 翻译难免限于本人水平有不准确的地方,建议英文水平不错的同学直接查看原版,有不足的地方欢迎指正
第一部分目录导航
假设场景 -- 图书销售网站
在本章中你会构建一个图书销售网站示例,称之为图书应用程序. 这个示例应用程序帮助我们查看查询中的关系. 本节中介绍了图书应用程序所需的数据库与EF Core的实体类部分
- 这里是图书应用程序的运行实例 http://efcoreinaction.com
图书应用程序的关系型数据库
虽然我们可以将作者,书,评论等所有数据都放到一张表中,但在关系型数据库中这样设计是很糟糕的,关系型数据库的规范是分离重复的数据,例如作者
我们有多种方式在数据库设计图书数据的各种部分,在本例中的数据库具有EF Core的主要关系类型,分别是以下三种:
- 一对一的关系: 书与优惠价格
- 一对多的关系: 书与评价
- 多对多的关系: 书与作者
一对一的关系: 书与价格
一个书可以有促销价格,这通过PriceOffers表的一个可选行实现的,这是一个一对一的例子(从技术来讲,这是一个1-0或1的关系,不过EF Core的处理方式是一样的);参见图2.1
The PriceOffers table has a foreign key that links to the books table's primary key
- PriceOffers表有一个连接到books表主键的外键
EF Core uses its conventions to detect that this is a one-to-one relationship. It therefore adds a unique index to the foreign key to ensure that there can only be one per book
- EF Core使用它的约定来检测这是一个一对一的关系,因此它为外键添加了唯一索引,确保每本书只能有一个优惠价格
计算图书的最终价格,需要通过外键找到与图书链接的优惠价格记录. 如果找到了记录,NewPrice会取代原书的价格,并将PromotionalText显示到屏幕上; 例如:
原价¥40现价¥9.9 温州印书场倒闭了,老板带着小姨子跑路了. 原价都是四十五十的,现价只要九块九
一对多的关系: 书的评论
顾客可以评价一本书;他们可以评星级,也可以留文字评论. 因为一本书可能没有一个评论或者有很多(无限)的评论,所以需要创建一张表保存这些数据. 在本例中它是Review表. Books表与Review表是一对多的关系, 如图2.2所示
The Review table is linked to the Books table via the foreign key called BookId
- Review表通过BookId外键链接到Books表
在显示图书介绍时,需要计算评论数量与平均星级评价. 这些通过一对多的关系去检索. 呈现在页面上是以下效果:
- 平均分 4.5 共有1000用户评论
多对多的关系: 图书与作者
一书本可能由一个人编写也可能由多人编写, 一个人(作者)可以著作一本书或多本书. 这是一个典型的多对多关系,在数据库中Books表保存图书数据,Authors表保存作者. Books和Authors表之间的链接就是多对多关系. 它们之间需要一张中间表. 参见图2.3
The BookAuthor table is the key to creating the many-to-many relationship and is known as a linking table
- BookAuthor表是多对多关系的核心,称为中间表
This table uses the foreign keys as the primary keys. Because primary keys must be unique, this ensures that only one link can exist between a book and an author
- BookAuthor表使用外键做为主键,因为主键必须是唯一的, 所以确保了书和作者之间只能有一个链接
多对多关系的页面展示如下
- 删库到跑路 - 我的程序一生 赵日天,萧炎,林动 著
EF6: 在EF6中定义多对多关系不需要链接类,EF6会自动创建隐藏的中间表.但是在EF Core中必须自己创建中间表
本章中未涉及的其他关系类型
使用EF Core你可以使用继承达到与之前一对一关系的类似结果,例如你可以将PriceOffer类继承自Book类. EF Core会使用第七章中介绍的table-per-hierarchy(TPH)实现. (子类和基类都需要包含在应用程序的DbContext中)
另一种是分层关系类型: 一组通过层次关系彼此关系的数据项目. 一个典型的例子是员工与经理,经理也是员工的一种. EF Core使用与一对五和一对多相同的方法来提供层次关系,在第七章详细讨论这类关系与如何配置
最终数据库的样子
图2.4展示了图书应用程序的数据库,在本章和第三章的示例中我们会使用到它. 图中包含了我们之前提到每张表与列的定义
注: PK表示主键,FK表示外键
为了帮助理解,图2.5展示了图片列表的输出(只有一书本). 图书应用程序需要访问数据库中的每一张表来构建图书列表,后面我会使用代码进行查询显示
注: 你可以在http://efcoreinaction.com/查看在线的示例,会有助于你理解本章的剩余部分,你也可以在Github仓库中找到这个示例在本地调试运行
EF Core映射数据库的类
我创建5个类对应着灵气库中的5张表,分别是Book,PriceOffer,Review,Author和BookAuthor(多对多中间表)
这些类称之为实休类,以突出它们是由EF Core映射到数据库的. 从软件工程的角度来看实体类是普通的.Net类(有时也被称为POCO)并没有什么特别之处. 因为它们是EF Core映射到数据库中的类,所以对其与其他类区分,称为实体类
图书应用程序中主要的实体类是Book类,如下图所示. 它引用了PriceOffer类,Review类型的集合以及BookAuthor的集合
我们使用了EF Core的约定配置实体类的主键,也就是类中int类型的Id属性. 数据库在添加新行时使用 Sql Identity 命令创建唯一键
为了保持示例的简单,示例中使用了EF Core的约定配置方法对数据库建模. .Net类的导航属性(比如ICollection)定义了我需要关系类型,例如Reviews属性的类型是ICollection,所以是一对多关系. 第六章和第七章介绍了建模的其他方法
本文的示例介绍了如何通过EF Core定义和创建数据库,如果你已经有了一个现有数据库,可以使用EF Core的逆行工程数据库的功能根据数据库表构建DbContext类和实体类,在11.3节中会介绍到,如果你不希望EF Core更改数据库结果而是通过SQL脚本或数据库部署工具自己来管理,可以在11.4节中找到方法