第3章 EF数据模型 本章导读 EF(EntityFramework)是模型开发中除LINQ 外另一种常用设计模式,使用EF 进行 项目开发时不需要去学习SQL 指令,程序员只要会应用LINQ 就能很方便地操作SQL Server数据库。本章将学习基于EF 的数据库优先、模型优先以及代码优先的三种设计模 式进行模型的快速创建,以及如何调用相关方法对模型中数据进行增、删、改、查处理。 本章要点 .EF 数据模型 .EF 的三种设计模式 .EF 模型数据处理 3.1 EntityFramework简介 EF(EntityFramework)是微软以ADO.NET 为基础开发的对象关系映射(Object RelationalMapping,ORM)解决方案。作为一种ORM 的数据访问框架,EF 将数据从对象 自动映射到关系数据库,不需要编写大量的数据访问代码,只要会应用LINQ 就可以如同 视频讲解Object对象一样方便地操作数据库,节省编写数据库访问代码的时间。 EF 框架具有良好的扩展性,除了可以访问SQLServer数据库,其他数据库只要按EF 所提供的接口实现对应的SQL 生成器与连接管理机制,就能在EF 中得到支持,当前EF 支 持的主要数据库如表3. 1所示。 表3. 1 EF支持的主要数据库 数据库名 MicrosoftSQLServer(含Expres 、ExpresLocalDb及Compact) Oracle MySql IBMDB2 、Informix与U2 Npgsql(PostgreSQL) SybaseSQLAnywhere、AdaptiveServer SQLite SynergyDBMS Firebird VistaDB 3.niyFrrk设计模式 2 Ettamewo EntityFramework在开发时主要有CodeFirst、ModelFirst以及DatabaseFirst三种 设计模式。对于初次使用EF的读者,建议从DatabaseFirst模式开始学习,熟悉了 ObjectContext和LINQtoEntities之后,再使用CodeFirst模式和ModelFirst模式 进行实践。下面依次介绍这三种设计模式的基本用法。视频讲解 3..aaaeFrst模式 21 Dtbsi DatabaseFirst模式,即数据库优先设计模式,是指以数据库设计为基础,通过设计好 的 数据库自动生成实体数据模型,从而实现整个系统开发的设计流程,该模式设计较简单, 适 合对数据库有一定了解的初学者 。 【例3-1】创建控制台应用程序,使用EF框架中的DatabaseFirst模式,基于Demo数视频讲解 据库在项目中创建实体类。 步骤1:Visatdo2017菜单栏中选择“ →“ →“ 选项,1 ulSui文件” 新建” 项目” 如图3. 所示 。 步骤2:创建控制台应用程序,命名为EF-DatabaseFirst, 2所示 。 如图3. 步骤3:在控制台应用程序上右击,选择“添加”→“新建项”选项,如图3.3所示。 步骤4:在“添加新项” 选择ADO.单击“添加”按钮,4 窗口, NET实体数据模型, 如图3. 所示 。 步骤5:在“实体数据模型向导”窗口的“选择模型内容”项中,选择“来自数据库的EF 设计器”,单击“下一步”按钮,如图3. 5所示。 59 图3. 1 创建新项目 图3. 2 创建控制台应用程序 图3. 3 添加新项 60 图3. 4 添加实体数据模型 图3. 5 选择模型 步骤6:在“实体数据模型向导”窗口的“选择您的数据连接”项中,单击“新建连接”按 钮,弹出“连接属性”窗口,“数据源”项选择为MicrosoftSQLServer(SqlClient),服(“) 务器 名”项设置为.qp选择数据库名称项设置为d单击“ 按钮,6所示。 \slexres, emo, 确定” 如图3. 61 图3. 6 数据库连接设置 步骤7:默认将连接字符串保存到App.g文件的ds标签内。单击“下 一步”按钮,7所示。 ConfiemoEntitie 如图3. 图3. 7 保存数据库连接字符串 62 步骤8:在“实体数据模型向导”窗口的“选择您的版本”项中,选择“实体框架6.”版 x 本,单击“ 按钮,8所示。 下一步” 如图3. 图3. 8 选择实体框架版本 步骤9:在“实体数据模型向导”窗口的“选择您的数据库对象和设置”项中,选择数据库 对象“表”, 确定所生成对象名称的单复数形式” 单击“完成”按钮,9所示。 选中“ 项, 如图3. 图3. 9 选择数据库中对象 63 6 4 步骤10:VisualStudio将开始加入EF的程序包,以及自数据库中查询待导入的对象, 并同步打开EDMDesigner编辑页面。除此,还生成了包括数据集合类Model1.Context.cs, 以及各数据表对应的student.cs、course.cs、sc.cs等实体类,如图3.10、图3.11所示。 图3.10 模型关系图 图3.11 自动生成的文件 其中,数据集合类Model1.Context.cs主要代码如下。 public partial class demoEntities2 : DbContext { public demoEntities2() : base("name=demoEntities2") { } protected override void OnModelCreating(DbModelBuilder modelBuilder) { throw new UnintentionalCodeFirstException(); } public virtual DbSetcourses { get; set; } public virtual DbSetscs { get; set; } public virtual DbSetstudents { get; set; } } 实体类sc.cs中代码如下。 public partial class sc 65 { public int sno { get; set; } public int cno { get; set; } public Nullable grade { get; set; } public virtual course course { get; set; } public virtual student student { get; set; } } 步骤11:创建完基本的模型后,打开Program.cs文件,添加基本的数据访问程序,进行 数据访问,编辑代码如下。 class Program { static void Main(string[] args) { demoEntities2 context=new demoEntities2(); var students = from item in context.students select new { no = item.sno, name = item.sname, age = item.age }; foreach (var item in students) { Console.WriteLine("No:{0},Name:{1},Age:{2}", item.no, item.name.Trim(), item.age); } } } 步骤12:运行网站结果如图3.12所示。 图3.12 数据库中查询的数据 3..MdlFrt模式 22 oeis ModelFirst模式,即模型优先设计模式,是从EF4 开始新增的功能,是指从实体数据 模型入手,根据模型创建数据库的开发模式。ModelFirst模式是当前使用较多的一种开发 模式,更符合面向对象的设计理念,只要在Designer内设计好模型的结构,就可以利用这个 视频讲解结构来生成数据库及对应代码。ModelFirst和DatabaseFirst两种模式是可逆的,都可以 得到数据库和实体数据模型。 【例3-2】创建控制台应用程序,按Demo 数据库中数据表的结构设计模型,使用EF 框架中的ModelFirst模式,在项目中生成数据库以及代码。 步骤1:创建控制台应用程序,命名为EF-ModelFirst。 步骤2:在控制台应用程序上右击,选择“添加”→“新建项”选项。在“添加新项”窗口, 选择ADO.e单击“添加”按钮。 NET 实体数据模型并命名为Modl, 步骤3:在“实体数据模型向导”窗口的“选择模型内容”项中,选择“空EF 设计器模型” 选项,单击“ 按钮, 13 所示。 完成” 如图3. 图3. 13 实体数据模型向导 步骤4:打开空白的Designer设计页面,工具箱会出现创建模型的控件,如同Windows rms 的窗体设计一样,可以从工具箱拖拽控件建立模型, 14 所示。 如图3.Fo 步骤5:参考Demo 数据库的模型,在工具箱中选中“实体”,按住鼠标左键拖放到 Designer内,产生新的模型,将名称改为student,在模型上右击,选择“新增”→“标量属性” 命令,可为其重命名, 15 所示。 如图3. 66 图3. 14 模型设计界面 步骤6:新增并修改student实体的sno、sname 、sex、age和dept五个属性,设计 student实体模型如图3. 16 所示。 图3.15 属性添加页面图3.t实体模型 16 studen 属性”2设置snsnseage 步骤7:依次选中每个属性,在“ 窗口的类型中按表3.o、ame 、x、 和dept五个属性的数据类型, 17 所示。 如图3. 表3.2 student实体属性 属性名字段描述数据类型主键可否为NULL sno 学号Int32 True False sname 姓名String False False sex 性别String False True age 年龄Int32 False True dept 部门String False True 67 图3.t属性 17 studen 表3. 步骤8:创建另外两个新实体course和sc, 18 所示。相关属性设置如表3. 如图3.3和 4所示。 图3. 18 各实体属性 表3.ore表实体属性 3 cus 属性名数据类型主键可否为NULL cno Int32 True False cname String False True tname String False False credit Int32 False False 68 表3.c表实体属性 4s 属性名数据类型主键可否为NULL sno Int32 True False cno Int32 True False grade Int32 False False 步骤9:建立实体之间的关联,为实体创建外键关联。在工具箱中选择“关联”选项,然 后分别选中student和sc实体,添加关联线,一个student对象可以同时拥有多个sc对象, 故为一对多的关系。同样为course实体和s如图3. c实体之间添加关联, 19所示。 在建立关联的同时,会产生“导航属性”选项,通过导航属性,就能直接浏览关联好的对 象。在Designer的空白处右击,在“属性”窗口将“以复数形式表示新对象”属性值设置为 True,如图3.rue,student产生数据表时对应的名称将设为 20所示。该属性值为 T s,e名称将设为cs,c名称将设为ss 。 studentcoursoursesc 20 模型属性设置 图3.19 各实体关系图图3. 步骤10:生成为数据库前,进行DbContext对象设置。在Designer上右击,选择“添加 代码生成项”选项, 21所示。 如图3. 步骤11:在“添加新项”窗口选择DbConet生成器,选择“EF6.otxt生成器” 选项,单击“ 按钮, 22所示。 txxDbCne 添加” 如图3. 步骤12:设置完成后,在Modeledmx项目下新增了ModlCnett 和Modlt 文件,如图3.1.e1.otx.e1. 23所示。 69 图3. 21 添加代码生成项 图3.xDbContext生成器 22 选择EF6. 步骤13:在Designer的空白处右击,选择“根据模型生成数据库”命令,如图3. 24 所示。 步骤14:在“生成数据库向导”窗口单击“新建连接”按钮,按例3-1中数据库的连接步 骤,连接到一个不含任何数据表的空白数据库demo2(demo2数据库需要读者自行创建)。 步骤15:在“摘要和设置”选项中出现DDL 项,显示数据库的定义语言命令画面,如图 70 图3. 23 新增模型代码 图3. 24 生成数据库操作 25 所示。若单击“上一步”按钮会回到“生成数据库”向导,单击“完成”按钮, 3.VisualStudio 将自动生成DDL 文件并打开,如图3. 26 所示 。 步骤16:直接单击左上角 的 按钮,可以将这个DLL 送到demo2数据库执行,当执行 完时,就可以看到数据库中创建了studentSet、courseSet以及scSet三张数据表,它们之间 也设置了ForeignKey的关联。 71 图3.摘要和设置”显示 25 “ 图3. 26 自动生成DDL 命令 如果使用的VisualStudio中未安装SQLServerDataTools,则无法在VisualStudio 中直接执行命令。此时,可以将DLL 复制到SQLServerManagementStudio中执行,同样 可以完成数据库架构更新的操作。 72 3..oeFrt模式 23Cdis CodeFirst模式,即代码优先设计模式,是通过编写程序代码的方式来定义数据的结 构,根据项目需求,撰写数据上下文类,程序运行时依据类创建数据表及相关属性,并转换成 实体模型。在开发中没有特别的GUI 工具,使用数据库的相关概念创建相关模型,适合熟 悉传统ADO.视频讲解 NET 开发的技术人员使用。 【例3-3】创建控制台应用程序,按Demo 数据库中的数据表的结构设计模型,使用EF 框架中的CodeFirst模式,对应的在项目中生成模型及数据库文件。 步骤1:创建控制台应用程序,命名为EF-CodeFirst。 步骤2:控制台应用程序上右击,选择“添加”→“新建项”选项。在“添加新项”窗口,选 择ADO.NET 实体数据模型并命名为Model1,单击“添加”按钮。 步骤3:在“实体数据模型向导”窗口的“选择模型内容”项中,选择空CodeFirst模型, 单击“完成” 如图3. 按钮, 27 所示。 图3. 27 模型选择 步骤4:添加完成后,VisualStudio会打开生成好的CodeFirst程序代码Model1。该 类继承自DbContext,相关的定义规则在类中均以注释代码的形式给出,简单修改后即可 使用。 Mode1.s源代码如下。 lc 73 7 4 public class Model1 : DbContext { //你的上下文已配置为从你的应用程序的配置文件(App.config 或Web.config) //使用Model1 连接字符串。默认情况下,此连接字符串针对你的LocalDb 实例上的 //EF_CodeFirst.Model1 数据库。 // //如果想要针对其他数据库和/或数据库提供程序,请在应用程序配置文件中修改Model1 //连接字符串。 public Model1() : base("name=Model1") { } //为你要在模型中包含的每种实体类型都添加DbSet。有关配置和使用Code First 模型 //的详细信息,请参阅http://go.microsoft.com/fwlink/? LinkId=390109。 // public virtual DbSet MyEntities { get; set; } } //public class MyEntity //{ // public int Id { get; set; } // public string Name { get; set; } //} 步骤5:修改Model1.cs文件,向demo3数据库创建一个MyStudents学生表,结构与 student表一致,编辑Model1.cs文件的Model1类代码如下。 public class Model1 : DbContext { public Model1() : base("name=Model1") { } public virtual DbSet MyStudents { get; set; } } 新建Student类,编辑代码如下。 public class Student { public int Id{ get; set; } //int 类型的Id 属性默认为实体表的主键 public string Sname { get; set; } public string Sex { get; set;} public int Age { get; set; } public string Dept { set; get; } } 75 使用编辑代码的方式编写CodeFirst模型时,如果未使用系统自动创建的类,则需要在 App.config或者Web.config中加入EF相关的配置,否则程序无法自动实现数据库的访问。 步骤6:在CodeFirst模式生成模型时,默认会使用SQLServerExpressLocalDb作为 目标的数据库服务器,如果要使用demo3数据库,需要对App.config中的属性进行设置。 原设置如下。 修改App.config文件部分设置如下。 < parameter value =" Data Srouce =. \ sqlexpress; Intergrated Security = True; MultipleActiveResultSets=True" /> 步骤7:在Program.cs文件的主程序中编写程序代码如下。 class Program { static void Main(string[] args) { Model1 model = new Model1(); model.Database.CreateIfNotExists(); } } 步骤8:执行应用程序,成功后查询数据库中数据表,如图3.28所示。 3.2.4 App.config的相关设置 在3.2.3节中介绍了CodeFirst模式生成数据库时,需要在App.config中进行相关的 7 6 图3.28 创建生成student表 设置。当需要变更数据库的类型时,需要对中的属性进行相 关设置。当需要变更数据库名称或连接账户时,需要对内的连接字 符串进行设置,常用的设置如下。 1.设置数据库类型为SQLServer(非LocalDb) < defaultConnectionFactory type ="System.Data.Infastructure.SqlConnectionFactory, EntityFramework"> < parameter value =" Data Srouce = MyDatabaseServer; Intergrated Security = True; MultipleActiveResultSets=True" /> 2.设置数据库类型为SQLServerCompact 3.设置数据库类型为SQLServerExpressLocalDb 4.设置CodeFirst的连接字符串 77 5.设置DatabaseFirst/ModelFirst的连接字符串 < add name =" BlogContext" connectionString =" metadata = res://*/BloggingModel. csdl|res://*/BloggingModel.ssdl|res://*/BloggingModel.msl; provider = System. Data.SqlClient provider connection string="data source=(localdb)\v11.0;initial catalog= Blogs;integratedsecurity=True;multipleactiveresultsets=True;" "providerName="System.Data.EntityClient" /> 3.2.5 由数据库生成模型 对已经存在的数据库也可以直接使用CodeFirst模型,基本方法是在ADO.NET 实体 数据模型向导中选择“来自数据库的CodeFirst”选项,如图3.29所示。其他的操作和 DatabaseFirst模式的设计步骤基本相同。只是在CodeFirst模式的设计对象中不支持存 储过程和函数,如图3.30所示。 图3.29 实体模型选择