EntityFramework_第1页
EntityFramework_第2页
EntityFramework_第3页
EntityFramework_第4页
EntityFramework_第5页
已阅读5页,还剩24页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

1、预备知识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与V

2、B9.0的编译器进性扩展,从而使其可以将LINQ编写的程序编译为可以被CLR2.0的JIT所理解的MSIL。LINQ技术的基础 - C#3.01. 自动属性2. 隐式类型3. 对象集合初始化器4. 匿名类5. 扩展方法6. Lambda表达式自动属性这个概念很简单,其简化了我们在.NET的时候手写一堆私有成员+属性的编程方式,我们只需要使用如下方式声明一个属性,编译器会自动生成所需的成员变量。publicclassCustomerpublicintId get;set; publicstringName get;set; 在我使用LINQ完成的项目中,使我了解到自动属性方便的一个用途如下:在使

3、用LINQ获取数据的过程中,我们常常需要使用select new语句查询出一个对象(往往是IEnumerable类型的)用于数据绑定。在一般情况下如果是直接绑定(如直接将查询结果赋给一个Gridview控件的DataSource属性)我们可以直接select new来返回一个匿名类的对象。如果我们还需要对这个集合对象进行进一步操作,我们将必须使用select newclass-name这样的语言返回一个类的对象,大部分情况下这个类只作为实体的一个结构而不需要完成一些操作操作,这时候使用自动属性来完成这个类将是非常简洁高效的。隐式类型这个名称可能对你很陌生,但是var这个关键字应该都用过,在C#

4、中使用var声明一个对象时,编译器会自动根据其赋值语句推断这个局部变量的类型。赋值以后,这个变量的类型也就确定而不可以再进行更改。另外var关键字也用于匿名类的声明。应用场合:var主要用途是表示一个LINQ查询的结果。这个结果可能是ObjectQuery或IQueryable类型的对象,也可能是一个简单的实体类型的对象。这时使用var声明这个对象可以节省很多代码书写上的时间。对象初始化器与集合初始化器在.NET2.0中构造一个对象的方法一是提供一个重载的构造函数,二是用默认的构造函数生成一个对象,然后对其属性进行赋值。在.NET3.5/C#3.0中我们有一种更好的方式来进行对象的初始化。那就

5、是使用对象初始化器。这个特性也是匿名类的一个基础,所以放在匿名类之前介绍。还是那就话,好的代码强于注释,下面用几个代码段说明初始化器:(代码出自:李永京的博客)基本用法:Useruser =newUser Id = 1, Name =YJingLee, Age = 22 ;嵌套使用:Useruser =newUser Id = 1, Name =YJingLee, Age = 22, Address=newAddress City =NanJing, Zip = 21000 ;类似于对象初始化器初始化一个对象,集合初始化器初始化一个集合,一句话,有了它你就不用在将元素通过Add逐个添加了。仍然

6、给出代码示例:基本使用:List num =newList 0, 1, 2, 6, 7, 8, 9 ;结合对象初始化器,我们可以写出如下简洁的代码:List user =newListnewUserId=1,Name=YJingLee,Age=22,newUserId=2,Name=XieQing,Age=25,;应用场合:还是前文提到的select newclass-name语法,后面可以直接接一个初始化器来将查询结果返回到这个对象。匿名类有了前文初始化器的介绍,匿名类就很简单了。我们可以使用new object initializer或new object, 来初始化一个匿名类或不确定类型

7、的数组。匿名类的对象需要使用var关键字声明。示例代码:varp1 =new Id = 1, Name =YJingLee, Age = 22 ;应用场合:还是同上面的例子提到的当直接使用select new object initializer这样的语法就是将一个LINQ查询的结果返回到一个匿名类中。扩展方法扩展方法是C#中新增的很重要的特性之一。其对于LINQ的实现起着关键的作用。在.NET2.0时代是没有LINQ的,所以.NET2.0以及之前版本中的集合类在设计的时候没有预留用于LINQ的方法。为了在不破坏这个类现有封装的前提下又可以为其添加LINQ的支持就需要用到扩展方法。扩展方法使用

8、上类似于静态方法,但在本质上其是实例方法。这是由于.NET3.5的运行环境仍然为CLR2.0所以语言不可能做很大的变革,这一切都是语法糖。下面仍然通过一段代码来说明扩展方法的实现:(代码出自:李永京)publicstaticclassExtensionspublicstaticboolIsValidEmailAddress(thisstrings)Regexregex =newRegex(w-.+(w-+.)+w-2,4$);returnregex.IsMatch(s);如上代码所示,扩展方法为一静态方法,声明于一个静态类,其参数前加上一个this关键字,参数的类型表示这个扩展方法要对这个类型

9、进行扩展。如上述代码表示其要对字符串类型进行扩展。在应用上扩展方法被作为其扩展的类型的静态方法来调用。如下:if(email.IsValidEmailAddress()Response.Write(YJingLee提示:这是一个正确的邮件地址);Lambda表达式Lambda表达式是对.NET2.0中匿名方法在语法形式上的进一步改进,仍然以代码说明:varinString = list.FindAll(delegate(strings) returns.Indexof(YJingLee) = 0; );使用Lambda表达式代码将更自然易懂。varinString = list.FindAll

10、(s = s.Indexof(YJingLee) = 0);可以看出,Lambda表达式格式为:(参数列表)=表达式或语句块另外我对于Lambda表达式树的概念还不是很明白,有明白的指点一下。.NET中的数据访问这一部分介绍.NET中不同的数据访问层的使用方式,由此得出Entity Framework在一个.NET系统中的应用及其在原有设计基础上的改变。从大的方面来看数据访问的设计方案基本有如下几类: DataSet 手写代码通过ADO.NET2.0连接类与数据库交互 ORM组件DataSet方案最基本的Dataset数据访问的实现使用下图表示:图1如图所示,DataSet与数据源之间通过Da

11、taAdapter连接,逻辑中直接访问DataSet获取数据,或是通过ADO.NET2.0的非连接类,或者通过强类型DataSet以一种类型安全的方式访问数据。缺点逻辑代码与数据访问代码耦合高。改进的的DataSet方案图2这种设计方式将业务所需的实体抽象出来,并把对DataSet的操作封装在其中,这样一定程序上解除业务逻辑与数据访问间的耦合。手写代码通过ADO.NET2.0连接类与数据库交互这种方式是我使用的最多的一种方式,其可以提供最大的控制能力,且效率最高,唯一的不足是当业务变化时修改数据访问代码的工作量比较大,通过代码生成器也能一定程度上解决这个问题ORM LINQ to SQL在.N

12、ET平台下ORM的解决方案有不少,本文只讨论两个微软官方的解决方案。先是LINQ to SQL技术。LINQ to SQL是一个将不再更新的技术。其有很多不足之处,如,不能灵活的定义对象模型与数据表之间的映射、无法扩展提供程序只能支持SQL Server等。这样数据访问层的设计如下所示:图3ORM ADO.NET Entity Framework作为下一代数据访问的技术领导者。Entity Framework的设计很多地方都保留了高扩展性。其最重要的一个改进在于其映射定义的灵活性。先来看下图:图4由图可以看出,使用Entity Framework可以充分的定义与数据库表映射的实体,并将这个实体

13、直接用于业务逻辑层或作为服务的数据契约。实体设计较其他技术的优势体现在以下几方面: 创建ComplexType(CSDL部分有讨论) EntitySet的继承使用Entity Framework后,可以将实体类的设计工作完全放在EDM的设计过程中,而不再需要手工写一些大同小异的代码,并且对这个实体模型(包含于EDM中)可以在运行时修改并生效。另外,开发人员与数据库直接打交道的次数将大大减少,大部分时间开发人员只需操作实体模型,框架会自动完成对数据库的操作。下文将详细讨论上图所示的EDM。深入了解Entity FrameworkEntity Framework的核心 EDM(Entity Dat

14、a Model)EDM概述实体数据模型,简称EDM,由三个概念组成。概念模型由概念架构定义语言文件 (.csdl)来定义,映射由映射规范语言文件 (.msl),存储模型(又称逻辑模型)由存储架构定义语言文件 (.ssdl)来定义。这三者合在一起就是EDM模式。EDM模式在项目中的表现形式就是扩展名为.edmx的文件。这个包含EDM的文件可以使用Visual Studio中的EDM设计器来设计。由于这个文件本质是一个xml文件,可以手工编辑此文件来自定义CSDL、MSL与SSDL这三部分。下面详细分析一下这个xml文件及三个其重要组成部分:这个文件展示了示例项目完整的EDM文件的XML形式:文件

15、这个设计器生成的文件的注释可以使你很清楚的明白这个EDM文件的组成。一点点分析一下,第一行表明这是一个xml文件。以下这一行是EDM的根节点,定义了一个表明版本的属性及这个EDM使用的命名空间:edmx:EdmxVersion=1.0xmlns:edmx=接下来由注释可以看到EDM被分为两部分,第一部分是EDM的核心,第二部分用于实体设计器,这一部分不用研究。第一部分中节点下定义了以下三部分:EDM之CSDLCSDL定义了EDM或者说是整个程序的灵魂部分 概念模型。当前流行的软件设计方法通常都是由设计其概念模型起步。说概念模型可能比较抽象一个更容易接受的名字就是实体类。实体类是面向对象设计中一

16、个最根本的组成部分,其体现了现实世界中对象作为一种计算中可以表示的对象设计方法。而EDM的CSDL就是要达到这样一个目的。这个在下文介绍Entity Framework优点时另有说明。这个文件完全以程序语言的角度来定义模型的概念。即其中定义的实体、主键、属性、关联等都是对应于.NET Framework中的类型。下面xml element来自作业提交系统(有删节):SchemaNamespace=ASSModelAlias=Selfxmlns=这部分XML文档,Schema是CSDL的根元素,其中定义的Namespace是用于ObjectContext与EntityClass的命名空间,Ali

17、as-别名为此命名空间Namespace指定一个易记的名称,在定义Alias之后,在此Schema内的Element均可以该Alias作为Namespace的别名。Alias的使用可以参考如下xml element:在这个根元素的内部的文档结构第一部分 实体容器大致如下:下面的表格说明了这些节点及其属性的作用EntityContainerNameEntityContainer的名称,其将作为产生的ObjectContext类的名称EntitySetNameObjectContext内与此Entity类型对应的属性名EntityTypeObjectContext内与此Entity类型对应的属性的

18、类型AssociationSetEnd有两个End子节点,分别描述建立此关系的两个EntitySetRole对应到Association中End节的Role属性,起到将AssociationSet与Association相关连的作用。FunctionImport详见存储过程设计部分可以看出,Entity与Assciation都被分开定义与两个部分,这样设计是出于当有多个EntityContainer时,其中的EntitySet或AssociationSet可以共享Entity或Association的定义。接下来看一下CSDL中最后一部分,Entity与Association的定义。首先是En

19、tity:下表说明了其属性及其子节点与子节点的属性的含义:EntityTypeNameEntity Class的名称Abstract是否为抽象类BaseType父类Key主键Property主键之属性Name属性名Property属性Name属性名Type属性类型Nullable是否允许nullMaxLength属性最大长度FixLength是否固定长度NavigationProperty关系属性Name属性名Relationship对应的AssociationFromRole、ToRole区别关系两方的父与子最后Association节,这是真正定义关系的地方。首先看示例:这一节符合以下结构

20、:属性及其子元素属性的说明: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外键

21、属性Name属性名另外上面示例未涉及的概念,如下:视图在EDM设计器中添加视图基本与添加实体表一致,所生成的xml自行对照。某些环境下可能无法添加视图,原因未知,另外对于没有主键的表目前版本EntityFramework支持不好,在设计器中无法添加,及时通过手工编辑xml的方式强行添加,在使用过程中也会出现问题。ComplexType(复杂类型)按MSDN中的例子,先描述如下场景。在一个销售系统中我们需要在一个订单中包含一个描述客户地址的实体,而这个实体又能良好的与存储模型映射起来,由于数据库不支持地址这种类型,所以我们可以将地址的每个字段与数据库相映射。且在概念模型中,及在C#代码可以控制的

22、范围内,地址仍然作为一个独立的类型存在。由于EDM设计器不支持以可视化方式创建Complex Type,我们需要手动编辑CSDL与MSL来完成复杂类型的创建与映射。这部分示例将在介绍MSL后给出。EDM之SSDL这个文件中描述了表、列、关系、主键及索引等数据库中存在的概念。SchemaNamespace=ASSModel.StoreAlias=SelfProvider=System.Data.SqlClientProviderManifestToken=2008xmlns:store=看文档的结构,SSDL与CSDL很详细,只是其中EntityType等使用数据库的概念的描述。这其中有一个需要

23、稍微介绍节点,DefiningQuery,首先看一下其出现的位置:EntityContainerEntitySetDefiningQuery通过查询定义一个SSDL的EntitySet特定于存储的查询语句DefiningQuery定义通过实体数据模型 (EDM) 内的客户端投影映射到数据存储视图的查询。此类映射是只读的。也就是说如果想要更新此类EntitySet,需要使用下文介绍存储过程时提到的定义更新实体的存储过程的方法,使用定义的存储过程来更新这样的EntitySet。当在实体类设计器中导入无主键的表时,会自动生成此类使用DefiningQuery定义的EntitySet,要式样Entit

24、y Framework提供的自动更新服务而不定义存储过程,需要给数据表添加一个适当的主键,删除DefiningQuery节点并更新数据模型。EDM之MSL这个文件即上面所述的CSDL与SSDL的对应,主要包括CSDL中属性与SSDL中列的对应。如上代码所示,MSL的根节点为Mapping,其中可以包含多个EntityContainerMapping(上例只有一个),每一个EntityContainerMapping对应着两个分别来自CSDL与SSDL的EntityContainer。这个EntityContainerMapping就是描述这两个EntityContainer间的对应。下面再给出

25、一段代码展示EntityContainerMapping的基本格式。同上文,下面列出这些节点的属性EntityContainerMappingStorageEntityContainerSSDL中的EntityContainer名称CdmEntityContainerCSDL中的EntityContainer名称EntitySetMappingEntityContainer中每个EntitySet的对应NameEntitySetMapping的名称EntityTypeMapping描述CSDL中EntityType与SSDL中EntityType的对应NameEntityTypeMapping

26、的名称TypeName对应CSDL内Entity的名称 格式:IsTypeOf()注:这个类及其子类将共享此EntityTypeMappingMappingFragment描述属性及字段间的对应StoreEntitySetSSDL中的EntitySet名称(由于CSDL中一个EntitySet可以对应多个SSDL中的EntitySet)ScalarProperty属性与字段对应NameCSDL中的属性名ColumnNameSSDL中的字段名称Condition详见说明2ColumnName列名Value值ModificationFunctionMappingCUD对应的存储过程InsertFu

27、nction/ UpdateFunction / DeleteFunctionFunctionNameQueryViewEntity SQLAssociationSetMapping描述CSDL中的AssociationSet与SSDL中的EntitySet的对应关系NameAssociationSetMapping的名称StoreEntitySetSSDL中EntitySet的名称TypeNameCSDL中AssociationSet的名称EndProperty一个AssociationSetMapping中有两个EndProperty分别对应CSDL中两个End RoleNameEndPr

28、operty的名称ScalarProperty关系属性对应NameCSDL中的属性名ColumnNameSSDL中的字段名称ModificationFunctionMappingC/D对应的存储过程InsertFunction/ DeleteFunctionFunctionNameQueryViewEntitySQLFunctionImportMapping用于描述CSDL与SSDL间函数及函数参数的对应(详见下文存储过程部分)说明1:以上表中很重要的一个属性是MappingFragment中的StoreEntitySet属性,就像这个属性的说明中所说,其描述了CSDL的Entity对应到的S

29、SDL的Entity的名称。这是实现下文EDM映射方案中第二条将一个概念模型的实体映射到多个存储模型的实体的关键设置。说明2:Contain这个元素及其属性的作用是,当多个概念模型实体映射到一个存储模型实体时,该元素的属性决定了在什么情况下一个概念模型实体映射到指定的存储模型实体。说明3:QueryView 元素定义概念模型中的实体与存储模型中的实体之间的只读映射。使用根据存储模型计算的 Entity SQL 查询定义此查询视图映射,并以概念模型中的实体表达结果集。同DefiningQuery定义的查询。此映射也是只读的。就是说如果想要更新此类EntitySet,也需要使用下文介绍存储过程时提

30、到的定义更新实体的存储过程的方法,使用定义的存储过程来更新这样的EntitySet。当多对多关联在存储模型中所映射到的实体表示关系架构中的链接表时,必须为此链接表在AssociationSetMapping 元素中定义一个QueryView元素。定义查询视图时,不能在 AssociactionSetMapping 元素上指定 StorageSetName 属性。定义查询视图时,AssociationSetMapping 元素不能同时包含 EndProperty 映射。EDM中存储过程的设计目前版本(VS2008SP1)的实体设计器对存储过程支持不完善,只能手工编辑这三个文件中的存储过程部分,包

31、括:1. CSDL中的FunctionImport元素,其属性及说明如下所示:FunctionImportName(在程序中调用的)函数的名称EntitySet当函数返回实体对象时,需使用此属性指定对应的EntitySetReturnType函数返回值的类型Parameter以下用于参数子节点中的属性定义Name参数的名称Type参数的类型Mode参数的传递方式(In, Out或InOut)MaxLength参数值最大长度Precision参数值的精确度,用于数字类型Scale浮点数小数位2. SSDL中的Function节FunctionName存储过程名称Aggregate是否为聚合函数(

32、存储过程)BuiltIn是否为内建存储过程NiladicFunction是否为无参数存储过程IsComposableTrue为自定义函数,False为存储过程ParameterTypeSemantics参数类型转换方式ReturnType存储过程返回类型3. MSL中的FunctionImportMapping节FunctionImportMappingFunctionImportNameCSDL中FunctionImport的名称FunctionNameSSDL中Function Element的名称4. 这面总结的是用于返回实体对象的查询(存储过程)。下面分别描述一下有关修改操作的存储过程

33、的使用:1. 使用插入、更新或删除实体数据的存储过程,需要修改如下两个文件:SSDL,对其的修改要求与上文表中列出的一致:MSL,需要对一下节点进行定义:EntityContainerMappingEntitySetMappingEntityContainer中每个EntitySet的对应EntityTypeMapping描述CSDL中EntityType与SSDL中EntityType的对应ModificationFunctionMappingCUD对应的存储过程InsertFunction/ UpdateFunction / DeleteFunctionFunctionName1. 使用创

34、建或删除在数据源中使用链接表实现的实体类型之间的多对多关系的存储过程需要修改如下两个文件:SSDL,对其的修改要求与上文表中列出的一致:MSL,需要对一下节点进行定义:EntityContainerMappingAssociationSetMapping描述CSDL中的AssociationSet与SSDL中的EntitySet的对应关系ModificationFunctionMappingC/D对应的存储过程InsertFunction/ DeleteFunctionFunctionNameEDM中ComplexType的设计再谈Complex Type,上文大致介绍了复杂类型的概念及作用,现在开始看一下具体怎样实现。前文已经提到实现复杂类型关键是在CSDL与MSL,而与SSDL无关。首先应该在CSDL中怎加这样一节,此节与节同级,其结构如下:节点及其属性含义如下:ComplexType复杂类型Name复杂类型的名称Property属性Name属性名Type属性类型Nu

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论