




已阅读5页,还剩28页未读, 继续免费阅读
版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
Entity Framework 教程目录 预备知识 2 LINQ技术 2 LINQ技术的基础 - C#3.0 2 自动属性 2 隐式类型 2 对象初始化器与集合初始化器 3 匿名类 3 扩展方法 4 Lambda表达式 4 .NET中的数据访问 4 DataSet方案 5 改进的的DataSet方案 5 手写代码通过ADO.NET2.0连接类与数据库交互 5 ORM LINQ to SQL 6 深入了解Entity Framework 7 Entity Framework的核心 EDM(Entity Data Model) 7 EDM概述 7 EDM之CSDL 7 EDM之SSDL 11 EDM之MSL 12 EDM中存储过程的设计 15 EDM中ComplexType的设计 16 实体数据模型映射方案 17 Entity Framework的原理及使用方式 18 各种使用方式总结 18 使用技巧及需要注意的问题 21 几种方法的性能分析及使用选择 21 其它操作EDM的方式 22 为什么要使用Entity Framework,限制条件及当前版本框架的问题 23 EDM中的DML 23 含有Association的EDM的使用 23 本文档主要介绍.NET开发中两项新技术,.NET平台语言中的语言集成查询技术 - LINQ,与ADO.NET中新增的数据访问层设计技术ADO.NET Entity Framework。ADO.NET的LINQ to Entity部分以LINQ为基础,为了完整性本文档首先介绍LINQ技术。 预备知识 LINQ技术 LINQ是.NET 3.5中新增的一种技术,这个技术扩展了.NET平台上的编程语言,使其可以更加方便的进行数据查询,单纯的LINQ技术主要完成对集合对象(如System.Collection下或System.Collection.Generic命名空间下的对象)的查询。结合LINQ Provider可以实现对XML文件(使用LINQ to XML 位于System.Xml.Linq命名空间下的类),数据库(可以使用LINQ to SQL或下文要详细介绍的LINQ to Entity)等对象的操作。 LINQ是一种运行时无关的技术,其运行于CLR2.0之上,微软对C#3.0与VB9.0的编译器进性扩展,从而使其可以将LINQ编写的程序编译为可以被CLR2.0的JIT所理解的MSIL。 LINQ技术的基础 - C#3.0 自动属性 隐式类型 对象集合初始化器 匿名类 扩展方法 Lambda表达式 自动属性 这个概念很简单,其简化了我们在.NET的时候手写一堆私有成员+属性的编程方式,我们只需要使用如下方式声明一个属性,编译器会自动生成所需的成员变量。 public class Customer public int Id get; set; public string Name get; set; 在我使用LINQ完成的项目中,使我了解到自动属性方便的一个用途如下: 在使用LINQ获取数据的过程中,我们常常需要使用select new语句查询出一个对象(往往是IEnumerable类型的)用于数据绑定。在一般情况下如果是直接绑定(如直接将查询结果赋给一个Gridview控件的DataSource属性)我们可以直接select new来返回一个匿名类的对象。如果我们还需要对这个集合对象进行进一步操作,我们将必须使用select new class-name这样的语言返回一个类的对象,大部分情况下这个类只作为实体的一个结构而不需要完成一些操作操作,这时候使用自动属性来完成这个类将是非常简洁高效的。 隐式类型 这个名称可能对你很陌生,但是var这个关键字应该都用过,在C#中使用var声明一个对象时,编译器会自动根据其赋值语句推断这个局部变量的类型。赋值以后,这个变量的类型也就确定而不可以再进行更改。另外var关键字也用于匿名类的声明。 应用场合:var主要用途是表示一个LINQ查询的结果。这个结果可能是ObjectQuery或IQueryable类型的对象,也可能是一个简单的实体类型的对象。这时使用var声明这个对象可以节省很多代码书写上的时间。 对象初始化器与集合初始化器 在.NET2.0中构造一个对象的方法一是提供一个重载的构造函数,二是用默认的构造函数生成一个对象,然后对其属性进行赋值。在.NET3.5/C#3.0中我们有一种更好的方式来进行对象的初始化。那就是使用对象初始化器。这个特性也是匿名类的一个基础,所以放在匿名类之前介绍。 还是那就话,好的代码强于注释,下面用几个代码段说明初始化器: (代码出自:李永京的博客 ) 基本用法: User user = new User Id = 1, Name = YJingLee, Age = 22 ; 嵌套使用: User user = new User Id = 1, Name = YJingLee, Age = 22, Address = new Address City = NanJing, Zip = 21000 ; 类似于对象初始化器初始化一个对象,集合初始化器初始化一个集合,一句话,有了它你就不用在将元素通过Add逐个添加了。仍然给出代码示例: 基本使用: List num = new List 0, 1, 2, 6, 7, 8, 9 ; 结合对象初始化器,我们可以写出如下简洁的代码: List user = new List new UserId=1,Name=YJingLee,Age=22, new UserId=2,Name=XieQing,Age=25, ; 应用场合: 还是前文提到的select new class-name语法,后面可以直接接一个初始化器来将查询结果返回到这个对象。 匿名类 有了前文初始化器的介绍,匿名类就很简单了。我们可以使用new object initializer 或new object, 来初始化一个匿名类或不确定类型的数组。匿名类的对象需要使用var关键字声明。示例代码: var p1 = new Id = 1, Name = YJingLee, Age = 22 ; 应用场合: 还是同上面的例子提到的当直接使用select new object initializer 这样的语法就是将一个LINQ查询的结果返回到一个匿名类中。 扩展方法 扩展方法是C#中新增的很重要的特性之一。其对于LINQ的实现起着关键的作用。在.NET2.0时代是没有LINQ的,所以.NET2.0以及之前版本中的集合类在设计的时候没有预留用于LINQ的方法。为了在不破坏这个类现有封装的前提下又可以为其添加LINQ的支持就需要用到扩展方法。 扩展方法使用上类似于静态方法,但在本质上其是实例方法。这是由于.NET3.5的运行环境仍然为CLR2.0所以语言不可能做很大的变革,这一切都是语法糖。 下面仍然通过一段代码来说明扩展方法的实现: (代码出自:李永京 ) public static class Extensions public static bool IsValidEmailAddress(this string s) Regex regex = new Regex(w-.+(w-+.)+w-2,4$); return regex.IsMatch(s); 如上代码所示,扩展方法为一静态方法,声明于一个静态类,其参数前加上一个this关键字,参数的类型表示这个扩展方法要对这个类型进行扩展。如上述代码表示其要对字符串类型进行扩展。 在应用上扩展方法被作为其扩展的类型的静态方法来调用。如下: if (email.IsValidEmailAddress() Response.Write(YJingLee提示:这是一个正确的邮件地址); Lambda表达式 Lambda表达式是对.NET2.0中匿名方法在语法形式上的进一步改进,仍然以代码说明: var inString = list.FindAll(delegate(string s) return s.Indexof(YJingLee) = 0; ); 使用Lambda表达式代码将更自然易懂。 var inString = list.FindAll(s = s.Indexof(YJingLee) = 0); 可以看出,Lambda表达式格式为:(参数列表)=表达式或语句块 另外我对于Lambda表达式树的概念还不是很明白,有明白的指点一下。 .NET中的数据访问 这一部分介绍.NET中不同的数据访问层的使用方式,由此得出Entity Framework在一个.NET系统中的应用及其在原有设计基础上的改变。从大的方面来看数据访问的设计方案基本有如下几类: DataSet 手写代码通过ADO.NET2.0连接类与数据库交互 ORM组件 DataSet方案 最基本的Dataset数据访问的实现使用下图表示: 图1 如图所示,DataSet与数据源之间通过DataAdapter连接,逻辑中直接访问DataSet获取数据,或是通过ADO.NET2.0的非连接类,或者通过强类型DataSet以一种类型安全的方式访问数据。 缺点逻辑代码与数据访问代码耦合高。 改进的的DataSet方案 图2 这种设计方式将业务所需的实体抽象出来,并把对DataSet的操作封装在其中,这样一定程序上解除业务逻辑与数据访问间的耦合。 手写代码通过ADO.NET2.0连接类与数据库交互 这种方式是我使用的最多的一种方式,其可以提供最大的控制能力,且效率最高,唯一的不足是当业务变化时修改数据访问代码的工作量比较大,通过代码生成器也能一定程度上解决这个问题 ORM LINQ to SQL 在.NET平台下ORM的解决方案有不少,本文只讨论两个微软官方的解决方案。先是LINQ to SQL技术。LINQ to SQL是一个将不再更新的技术。其有很多不足之处,如,不能灵活的定义对象模型与数据表之间的映射、无法扩展提供程序只能支持SQL Server等。 这样数据访问层的设计如下所示: 图3 ORM ADO.NET Entity Framework 作为下一代数据访问的技术领导者。Entity Framework的设计很多地方都保留了高扩展性。其最重要的一个改进在于其映射定义的灵活性。先来看下图: 图4 由图可以看出,使用Entity Framework可以充分的定义与数据库表映射的实体,并将这个实体直接用于业务逻辑层或作为服务的数据契约。实体设计较其他技术的优势体现在以下几方面: 创建ComplexType(CSDL部分有讨论) EntitySet的继承 使用Entity Framework后,可以将实体类的设计工作完全放在EDM的设计过程中,而不再需要手工写一些大同小异的代码,并且对这个实体模型(包含于EDM中)可以在运行时修改并生效。另外,开发人员与数据库直接打交道的次数将大大减少,大部分时间开发人员只需操作实体模型,框架会自动完成对数据库的操作。下文将详细讨论上图所示的EDM。 深入了解Entity Framework Entity Framework的核心 EDM(Entity Data Model) EDM概述 实体数据模型,简称EDM,由三个概念组成。概念模型由概念架构定义语言文件 (.csdl)来定义,映射由映射规范语言文件 (.msl),存储模型(又称逻辑模型)由存储架构定义语言文件 (.ssdl)来定义。这三者合在一起就是EDM模式。EDM模式在项目中的表现形式就是扩展名为.edmx的文件。这个包含EDM的文件可以使用Visual Studio中的EDM设计器来设计。由于这个文件本质是一个xml文件,可以手工编辑此文件来自定义CSDL、MSL与SSDL这三部分。下面详细分析一下这个xml文件及三个其重要组成部分: 这个文件展示了示例项目完整的EDM文件的XML形式: 文件 这个设计器生成的文件的注释可以使你很清楚的明白这个EDM文件的组成。一点点分析一下,第一行表明这是一个xml文件。 以下这一行是EDM的根节点,定义了一个表明版本的属性及这个EDM使用的命名空间: 接下来由注释可以看到EDM被分为两部分,第一部分是EDM的核心,第二部分用于实体设计器,这一部分不用研究。 第一部分中节点下定义了以下三部分: EDM之CSDL CSDL定义了EDM或者说是整个程序的灵魂部分 概念模型。当前流行的软件设计方法通常都是由设计其概念模型起步。说概念模型可能比较抽象一个更容易接受的名字就是实体类。实体类是面向对象设计中一个最根本的组成部分,其体现了现实世界中对象作为一种计算中可以表示的对象设计方法。而EDM的CSDL就是要达到这样一个目的。这个在下文介绍Entity Framework优点时另有说明。 这个文件完全以程序语言的角度来定义模型的概念。即其中定义的实体、主键、属性、关联等都是对应于.NET Framework中的类型。下面xml element来自作业提交系统(有删节): 这部分XML文档,Schema是CSDL的根元素,其中定义的Namespace是用于ObjectContext与EntityClass的命名空间,Alias-别名为此命名空间Namespace指定一个易记的名称,在定义Alias之后,在此Schema内的Element均可以该Alias作为Namespace的别名。Alias的使用可以参考如下xml element: 在这个根元素的内部的文档结构第一部分 实体容器大致如下: 下面的表格说明了这些节点及其属性的作用 EntityContainerNameEntityContainer的名称,其将作为产生的ObjectContext类的名称EntitySetNameObjectContext内与此Entity类型对应的属性名EntityTypeObjectContext内与此Entity类型对应的属性的类型AssociationSetEnd有两个End子节点,分别描述建立此关系的两个EntitySetRole对应到Association中End节的Role属性,起到将AssociationSet与Association相关连的作用。FunctionImport详见存储过程设计部分可以看出,Entity与Assciation都被分开定义与两个部分,这样设计是出于当有多个EntityContainer时,其中的EntitySet或AssociationSet可以共享Entity或Association的定义。 接下来看一下CSDL中最后一部分,Entity与Association的定义。 首先是Entity: 下表说明了其属性及其子节点与子节点的属性的含义: EntityTypeNameEntity Class的名称Abstract是否为抽象类BaseType父类Key主键Property主键之属性Name属性名Property属性Name属性名Type属性类型Nullable是否允许nullMaxLength属性最大长度FixLength是否固定长度NavigationProperty关系属性Name属性名Relationship对应的AssociationFromRole、ToRole区别关系两方的父与子最后Association节,这是真正定义关系的地方。首先看示例: 这一节符合以下结构: 属性及其子元素属性的说明: AssociationNameAssociation的名称End类似于AssociationSet,Association也有两个End节点。NameEnd名称TypeEntityType的名称Role此End的Role,与AssociationSet的End的Role属性相联系Multiplicity关联多重性,值为0、1或*ReferentialConstraint外键条件限制Principal主要条件Role对应于End中的RolePropertyRef外键属性Name属性名称Dependent依存条件Role对应于End中的RolePropertyRef外键属性Name属性名另外上面示例未涉及的概念,如下: 视图 在EDM设计器中添加视图基本与添加实体表一致,所生成的xml自行对照。某些环境下可能无法添加视图,原因未知,另外对于没有主键的表目前版本EntityFramework支持不好,在设计器中无法添加,及时通过手工编辑xml的方式强行添加,在使用过程中也会出现问题。 ComplexType(复杂类型) 按MSDN中的例子,先描述如下场景。在一个销售系统中我们需要在一个订单中包含一个描述客户地址的实体,而这个实体又能良好的与存储模型映射起来,由于数据库不支持地址这种类型,所以我们可以将地址的每个字段与数据库相映射。且在概念模型中,及在C#代码可以控制的范围内,地址仍然作为一个独立的类型存在。由于EDM设计器不支持以可视化方式创建Complex Type,我们需要手动编辑CSDL与MSL来完成复杂类型的创建与映射。这部分示例将在介绍MSL后给出。 EDM之SSDL 这个文件中描述了表、列、关系、主键及索引等数据库中存在的概念。 看文档的结构,SSDL与CSDL很详细,只是其中EntityType等使用数据库的概念的描述。 这其中有一个需要稍微介绍节点,DefiningQuery,首先看一下其出现的位置: EntityContainerEntitySetDefiningQuery通过查询定义一个SSDL的EntitySet特定于存储的查询语句DefiningQuery定义通过实体数据模型 (EDM) 内的客户端投影映射到数据存储视图的查询。此类映射是只读的。也就是说如果想要更新此类EntitySet,需要使用下文介绍存储过程时提到的定义更新实体的存储过程的方法,使用定义的存储过程来更新这样的EntitySet。当在实体类设计器中导入无主键的表时,会自动生成此类使用DefiningQuery定义的EntitySet,要式样Entity Framework提供的自动更新服务而不定义存储过程,需要给数据表添加一个适当的主键,删除DefiningQuery节点并更新数据模型。 EDM之MSL 这个文件即上面所述的CSDL与SSDL的对应,主要包括CSDL中属性与SSDL中列的对应。 如上代码所示,MSL的根节点为Mapping,其中可以包含多个EntityContainerMapping(上例只有一个),每一个EntityContainerMapping对应着两个分别来自CSDL与SSDL的EntityContainer。这个EntityContainerMapping就是描述这两个EntityContainer间的对应。下面再给出一段代码展示EntityContainerMapping的基本格式。 同上文,下面列出这些节点的属性 EntityContainerMappingStorageEntityContainerSSDL中的EntityContainer名称CdmEntityContainerCSDL中的EntityContainer名称EntitySetMappingEntityContainer中每个EntitySet的对应NameEntitySetMapping的名称EntityTypeMapping描述CSDL中EntityType与SSDL中EntityType的对应NameEntityTypeMapping的名称TypeName对应CSDL内Entity的名称 格式:IsTypeOf() 注:这个类及其子类将共享此EntityTypeMappingMappingFragment描述属性及字段间的对应StoreEntitySetSSDL中的EntitySet名称 (由于CSDL中一个EntitySet可以对应多个SSDL中的EntitySet)ScalarProperty属性与字段对应NameCSDL中的属性名ColumnNameSSDL中的字段名称Condition详见说明2ColumnName列名Value值ModificationFunctionMappingCUD对应的存储过程InsertFunction/ UpdateFunction / DeleteFunctionFunctionNameQueryViewEntity SQLAssociationSetMapping描述CSDL中的AssociationSet与SSDL中的EntitySet的对应关系NameAssociationSetMapping的名称StoreEntitySetSSDL中EntitySet的名称TypeNameCSDL中AssociationSet的名称EndProperty一个AssociationSetMapping中有两个EndProperty 分别对应CSDL中两个End RoleNameEndProperty的名称ScalarProperty关系属性对应NameCSDL中的属性名ColumnNameSSDL中的字段名称ModificationFunctionMappingC/D对应的存储过程InsertFunction/ DeleteFunctionFunctionNameQueryViewEntitySQLFunctionImportMapping用于描述CSDL与SSDL间函数及函数参数的对应(详见下文存储过程部分)说明1:以上表中很重要的一个属性是MappingFragment中的StoreEntitySet属性,就像这个属性的说明中所说,其描述了CSDL的Entity对应到的SSDL的Entity的名称。这是实现下文EDM映射方案中第二条将一个概念模型的实体映射到多个存储模型的实体的关键设置。 说明2:Contain这个元素及其属性的作用是,当多个概念模型实体映射到一个存储模型实体时,该元素的属性决定了在什么情况下一个概念模型实体映射到指定的存储模型实体。 说明3:QueryView 元素定义概念模型中的实体与存储模型中的实体之间的只读映射。使用根据存储模型计算的 Entity SQL 查询定义此查询视图映射,并以概念模型中的实体表达结果集。同DefiningQuery定义的查询。此映射也是只读的。就是说如果想要更新此类EntitySet,也需要使用下文介绍存储过程时提到的定义更新实体的存储过程的方法,使用定义的存储过程来更新这样的EntitySet。当多对多关联在存储模型中所映射到的实体表示关系架构中的链接表时,必须为此链接表在AssociationSetMapping 元素中定义一个QueryView元素。定义查询视图时,不能在 AssociactionSetMapping 元素上指定 StorageSetName 属性。定义查询视图时,AssociationSetMapping 元素不能同时包含 EndProperty 映射。 EDM中存储过程的设计 目前版本(VS2008SP1)的实体设计器对存储过程支持不完善,只能手工编辑这三个文件中的存储过程部分,包括: CSDL中的FunctionImport元素,其属性及说明如下所示: FunctionImportName(在程序中调用的)函数的名称EntitySet当函数返回实体对象时,需使用此属性指定对应的EntitySetReturnType函数返回值的类型Parameter以下用于参数子节点中的属性定义Name参数的名称Type参数的类型Mode参数的传递方式(In, Out或InOut)MaxLength参数值最大长度Precision参数值的精确度,用于数字类型Scale浮点数小数位 SSDL中的Function节 FunctionName存储过程名称Aggregate是否为聚合函数(存储过程)BuiltIn是否为内建存储过程NiladicFunction是否为无参数存储过程IsComposableTrue为自定义函数,False为存储过程ParameterTypeSemantics参数类型转换方式ReturnType存储过程返回类型 MSL中的FunctionImportMapping节 FunctionImportMappingFunctionImportNameCSDL中FunctionImport的名称FunctionNameSSDL中Function Element的名称 这面总结的是用于返回实体对象的查询(存储过程)。 下面分别描述一下有关修改操作的存储过程的使用: 使用插入、更新或删除实体数据的存储过程,需要修改如下两个文件:SSDL,对其的修改要求与上文表中列出的一致
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- T/CACC 0001-2024车载软件技术触控界面感知流畅性技术要求及试验方法
- 2025福建厦门集美区乐海小学产假顶岗校医招聘1人备考考试题库附答案解析
- 2025湖南岳阳新天地保安服务公司招聘总经理助理1人备考练习题库及答案解析
- 2025广西桂林兴安县乡镇所属事业单位直接考核招聘“三支一扶”服务期满人员4人笔试参考题库附答案解析
- 中国华电战略发展研究中心招聘4人备考考试题库附答案解析
- 工程质量管理控制论文
- 2025河南中航光电科技股份有限公司招聘备考考试题库附答案解析
- 中国水利水电科学研究院岩土工程研究所科研助理招聘2人备考考试题库附答案解析
- 2025北京市房山区燕山教育委员会所属事业单位第三批招聘教师13人备考考试题库附答案解析
- “梦想靠岸”招商银行沈阳分行2026校园招聘备考考试题库附答案解析
- 海水的秘密课件
- 系统运维期月度运行维护报告范文
- 2025-2026学年人教版七年级英语上册starterunit1-3单元测试卷(含答案)
- 辽宁省点石联考2025-2026学年高三上学期9月开学英语试题(含答案)
- 2025年乡镇文旅部门工作人员招聘考试必-备知识点与模拟题集
- 抖音达人签约合同协议书
- 森林消防队森林火灾扑救知识培训考试题库题库(附含答案)
- 湖南美术出版社二年级上册美术教学计划
- 2025年西藏自治区事业单位招聘考试综合类专业能力测试试卷(新闻类)押题卷
- VOCs治理设备培训
- 答案时代:AI顾问式电商崛起
评论
0/150
提交评论