目录
Entity Framework (EF) 是一个开源的对象关系映射 (ORM) 框架,它可以使 .NET 开发者能够使用 LINQ 查询关系型数据库,并且可以在 .NET 对象和数据库间转换数据。EF 提供了一种高级的抽象,让开发者不需要直接编写 SQL 查询和处理数据转换。
EF支持三种主要的开发模式:代码优先(Code First)、数据库优先(Database First)和模型优先(Model First)。下面将结合实际案例,详细讲解这三种模式,帮助初学者轻松理解和掌握。
一、Entity Framework概述
Entity Framework通过提供一组丰富的API和工具,使得数据访问层的开发变得更加简单和高效。它支持多种数据库系统,如SQL Server、MySQL、Oracle等,并允许开发人员使用LINQ(Language Integrated Query)来查询和操作数据。
二、Entity Framework的核心组成部分
Entity Data Model (EDM):
- 概念层(CSDL, Conceptual Schema Definition Language):定义了应用程序中的实体和它们之间的关系,这些实体对应于数据库中的表或视图。CSDL是EDM的“灵魂”部分,它用实体类表示数据库中的对象。
- 存储层(SSDL, Store Schema Definition Language):描述了数据库的实际结构,包括表、列、关系、主键及索引等。SSDL将数据库中的对象信息加载到EF中,并描述数据库对象的结构信息。
- 映射层(MSL, Mapping Specification Language):负责将概念层(CSDL)与存储层(SSDL)进行映射,确保应用程序中的实体能够正确地映射到数据库中的表或视图。
这些部分通常以XML格式定义,并存储在.edmx文件中,该文件是EF实现ORM的关键配置文件。
Entity Client:
- Entity Client是EF提供的一套类似于ADO.NET的数据库操作类,它主要用于操作EDM。与ADO.NET直接向数据库发送SQL命令不同,Entity Client是向EDM发送Entity SQL(EF特有的SQL方言),然后由EF将其转换为数据库可理解的SQL语句。
Object Services:
- Object Services提供了丰富的API,允许开发人员以面向对象的方式操作数据。这些API隐藏了底层数据库操作的复杂性,使得开发人员可以更加专注于业务逻辑的实现。
ADO.NET Provider:
- ADO.NET Provider是EF与数据库之间的桥梁,它负责将Entity Client的操作命令翻译为数据库的SQL语句,并执行这些语句。Microsoft默认实现了对SQL Server的ADO.NET Provider,但也可以通过其他数据库厂商提供的插件来支持其他数据库。
三、分层结构
从逻辑上讲,EF框架的分层结构可以归纳为以下几个层次:
应用程序层:
- 开发人员在这一层编写业务逻辑代码,通过EF提供的API来操作数据。这些API以面向对象的方式封装了数据库操作,使得开发人员可以像操作普通对象一样操作数据库中的数据。
Entity Framework层:
- 这一层是EF框架的核心,它包含了EDM、Entity Client、Object Services等关键组成部分。EF层负责将应用程序层的请求转换为数据库可理解的SQL语句,并将执行结果返回给应用程序层。
数据库层:
- 数据库层是实际存储数据的地方,它可以是任何支持ADO.NET的关系型数据库。ADO.NET Provider负责将EF层生成的SQL语句发送到数据库层执行,并将执行结果返回给EF层。
四、EF 主要的功能包括
- 通过 LINQ 查询数据
- 跟踪对象的状态变化并将这些变化持久化到数据库
- 支持事务处理
- 支持数据库迁移,即可以根据模型变化自动更新数据库结构。
五、三种开发模式详解
1. 代码优先(Code First)
核心思想:先编写实体类和数据上下文(DbContext),然后根据这些代码生成数据库。
适用场景:适用于新项目,或对数据库结构有完全控制权的情况。
实际案例:
假设我们要开发一个简单的博客系统,包含作者(Author)和文章(Post)两个实体。
1)定义实体类:
public class Author { public int AuthorId { get; set; } public string Name { get; set; } } public class Post { public int PostId { get; set; } public string Title { get; set; } public string Content { get; set; } public int AuthorId { get; set; } public Author Author { get; set; } }
2)定义数据上下文:
public class BlogContext : DbContext { public DbSet<Author> Authors { get; set; } public DbSet<Post> Posts { get; set; } protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder) { optionsBuilder.UseSqlServer(@"Server=(localdb)\mssqllocaldb;Database=BlogDb;Trusted_Connection=True;"); } }
3)使用迁移生成数据库:
在Visual Studio中,通过Package Manager Console运行以下命令:
Enable-Migrations Add-Migration InitialCreate Update-Database
这些命令会生成数据库迁移文件,并根据迁移文件创建数据库。
2. 数据库优先(Database First)
核心思想:从现有数据库生成实体类和映射文件,然后在此基础上进行开发。
适用场景:适用于已有数据库的情况,如维护现有系统或集成第三方数据库。
实际案例:
假设我们有一个现成的数据库,包含Authors和Posts两个表。
3. 模型优先(Model First)
核心思想:先设计数据模型,然后根据模型生成数据库。
适用场景:适用于从零开始设计数据模型的情况,或需要高度定制数据库结构的情况。
实际案例:
1)在Visual Studio中设计模型:
通过添加“ADO.NET Entity Data Model”项,选择“空模型”,并使用设计器添加实体和关系。 2)生成数据库脚本:
设计完成后,右键点击模型图,选择“生成数据库脚本”,将生成的SQL脚本在数据库中执行,以创建数据库和表。
3)使用生成的实体类进行数据操作:
与Database First类似,Model First也生成了实体类,可以直接在代码中使用。
使用Entity Framework Power Tools或dotnet ef工具生成模型:
在Visual Studio中,可以通过添加“ADO.NET Entity Data Model”项,并选择“从数据库生成模型”来生成实体类和映射文件。或者使用dotnet ef工具:
dotnet ef dbcontext scaffold "Server=(localdb)\mssqllocaldb;Database=ExistingDb;Trusted_Connection=True;" Microsoft.EntityFrameworkCore.SqlServer -o Models
这将根据数据库中的表生成相应的实体类和DbContext。
使用生成的实体类进行数据操作:
生成的实体类可以直接在代码中使用,进行CRUD操作。
六、总结
Entity Framework的三种开发模式各有优缺点和适用场景。Code First模式提供了最大的灵活性,适合新项目或对数据库结构有完全控制权的情况;Database First模式适用于已有数据库的情况,可以快速生成实体类和映射文件;Model First模式则适用于从零开始设计数据模型的情况。根据项目的具体需求选择合适的开发模式