什么是Entity Framework
Entity Framework
是一个对象关系映射O/RM
框架。
Entity Framework
让开发者可以像操作领域对象(domain-specific objects)那样操作关系型数据(relational data)。
Entity Framework
减少了大部分通常需要编写的数据操作代码。
Entity Framework
中可以使用LINQ
来查询数据,使用强类型(strongly typed objects)来检索和操作数据。
Entity Framework
提供了以下服务,使开发者可以更加侧重于程序业务逻辑,而非数据访问的基本操作。
- 状态或变更跟踪(change tracking)
- 身份或主键识别(identity resolution)
- 懒加载(lazy loading)
- 查询翻译(query translation)
Entity Framework是ADO.NET
的加强,它给开发者提供了数据库访问和存储的自动化机制。
Entity Framework是一个开源框架。
什么是O/RM
O/RM是一种工具,可以自动地把领域对象数据存储到关系型数据库(如MS SQL Server),而不需要大量的编码。
O/RM包含三个重要的部分:
领域对象(Domain class objects):我们定义的类。
关系型数据库对象(Relational database objects):数据库表,视图,存储过程等。
映射信息(Mapping information):领域对象与关系型数据库对象之间转换的信息。
O/RM允许开发者把数据库设计和领域对象设计独立开,让程序更具有可维护性和可扩展性。
它还提供了基本的增删改查的功能,开发者不需要手动再编写这部分代码。
一个典型的数据库与应用程序的O/RM交互如下图所示:
Entity Framework的结构
Entity Framework的总体结构如下图所示。
EDM(Entity Data Model):EDM包含三个主要的部分 - 概念模型(Conceptual model
)、存储模型(Storage model
)和映射(Mapping
)。
Conceptual model
:概念模型包含了模型的类定义,以及类之间的关系。概念模型的设计独立于数据库表设计。Storage model
:存储模型是数据库设计模型,包含了数据库表,视图,存储过程,以及它们的之间的关系和键。Mapping
:映射包含了概念模型映射到存储模型的相关信息。
LINQ to Entities:一种基于对象模型编写的查询语言,它将返回概念模型中设计的实体。
Entity SQL:另一种和LINQ to Entities相似的查询语言,但是它们还是有一些差异的,开发者还是需要单独花时间去学习它。
Object Service:数据库数据访问的主要入口,主要职责是物化(materialization),把Entity Client Data Provider返回的数据转换成实体对象结构。
Entity Client Data Provider:把LINQ to Entities或Entity SQL转换成数据库SQL。和ADO.Net Data Provider进行通讯,发送或检索数据库数据。
ADO.Net Data Provider:ADO.Net Data Provider
使用标准的ADO.Net
和数据库进行交互。
Entity Framework的开发模式
Entity Framework
提供了三种开发模式:
Code First
Database First
Model First
Code First:
在Code First
的开发模式中,要避免使用视觉模型设计器(EDMX
),一般是先编写POCO
类,然后根据这些类去生成数据库。
那些遵循领域驱动开发(DDD)原则的开发者,更倾向于一开始先编写自己的领域类,然后再生成数据库来实现数据持久化。
Database First:
通过已有的数据库来生成EDMX(Entity Data Model)
的开发模式就是Database First
的开发模式。
如果数据库变更了,EDMX(Entity Data Model)
也会更新。同时,Database First
也支持存储过程,视图等。
Model First:
Model First
是Code First
和Database First
的一种折中开发模式,它提供视觉模型设计器(EDMX)来设计数据模型,然后根据数据库模型来生成数据库以及领域类。
总结:
Code First
是先编写领域类,然后根据类来生成数据库,无视觉模型设计器(EDMX)。Database First
是根据数据库生成视觉模型设计器(EDMX)及领域类。Model First
是先生成视觉模型设计器(EDMX),然后根据EDMX生成数据库及领域类。
选择Entity Framework开发模式
1. 如果你有一个现成的程序,并且已经定义了领域类,那么,可以使用Code First
的开发模式来生成数据库进行开发。
如果你有已个现成的数据库,那么,可以使用
Database First
的开发模式来生成EDM进行开发。如果你没有现成的数据库,也没有定义好的领域类,而你更倾向于使用图形化界面来设计数据库模型,那么,可以使用
Model First
的开发模式进行开发。
我个人的话,任何情景都会使用Code First
的开发模式,因为它比较灵活,但是对开发者本身的要求会更高一些。
DbContext
DbContext
是Entity Framework
的一个重要部分,它是领域或实体类与数据库之间的桥梁。
DbContext
是一个很重要的类,主要职责是以对象的方式和数据进行交互,它包含以下活动:
EntitySet
:DbContext
包含实体集合(DbSet<TEntity>
),把实体映射到数据库表。
Querying
:DbContext
把LINQ to Entities
查询转换成SQL
查询,并发送到数据库。
Change Tracking
:DbContext
会跟踪从数据库查询出来的实体的状态变更。
Persisting Data
:DbContext
根据实体的状态提供插入,更新和删除等数据库操作。
Caching
:DbContext
默认实现一级缓存,在Context
类的生命周期期间,它会保存检索出来的实体。
Manage Relationship
:Database First
或Model First
中,使用CSDL,MSL,SSDL来管理关系,在Code First
中使用Fluent API
来管理关系。
Object Materialization
:DbContext
把表原始数据转换成实体对象。
实体生命周期
在实体的生命期中,每个实体都有一个基于上下文(DbContext
)的操作的实体状态。
实体状态是一个System.Data.Entity.EntityState
类型的枚举,它包含以下的值:
Added
:实体正在被上下文跟踪,但还不存在于数据库中。
Deleted
:实体正在被上下文跟踪并存在于数据库,但被标记为从数据库删除。
Modified
:实体正在被上下文跟踪并存在于数据库,而且实体的一些或所有属性的值被修改了。
Unchanged
:实体正在被上下文跟踪并存在于数据库,但实体的所有属性值都没被修改。
Detached
:实体不被上下文跟踪。
下图说明了实体状态如何影响数据库操作。
1. 新的实体具有Added
的状态,DbContext
后续会在数据库中执行插入操作。
通过
LINQ
检索出来的实体具有Unchanged
的状态,但如果调用了AsNoTracking()
方法,其状态为Detached
。修改了检索出来的实体的属性值,实体会修改状态为
Modified
,DbContext
后续会在数据库中执行更新操作。需要删除的实体会具有
Deleted
的状态,DbContext
后续会在数据库中执行删除操作。对于
DbContext
中已有的实体,可以通过dbContext.Entry(entity).State = EntityState.Detached
的方式把状态设置为Detached
。
Entity Framework版本
版本 | 引入功能 |
---|---|
EF 3.5 | Database First 模式下基本的O/RM 支持。 |
EF 4.0 | POCO 的支持, 懒加载, 可测试性提升,定制化代码生成,以及引入Model First 开发模式。 |
EF 4.1 | 在ObjectContext 的基础上简化了DBContext API,引入Code First 开发模式。 |
EF 4.3 | 引入Code First Migrations ,可以根据定义的Code First 模型来创建或修改数据库。 |
EF 5.0 | 宣布EF为开源项目。引入了枚举支持,表值函数, 空间数据类型,模型多图表,设计界面着色形状,批量导入存储过程,EF Power Tools ,以及各种性能提升。 |
EF 6.0 | 引入了许多Code First & EF 设计相关的新功能,如异步操作(asynchronous ),弹性连接(connection resiliency),依赖解析(dependency resolution )等。 |
注:Entity Framework Core不在本文讨论范围。