深入解读 Entity Framework 40和41.docx_第1页
深入解读 Entity Framework 40和41.docx_第2页
深入解读 Entity Framework 40和41.docx_第3页
深入解读 Entity Framework 40和41.docx_第4页
深入解读 Entity Framework 40和41.docx_第5页
已阅读5页,还剩3页未读 继续免费阅读

下载本文档

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

文档简介

深入解读 Entity Framework 4.0和4.1 记得去年初就开始关注Entity Framework,那时只是简单测试了一下,发现较之Nhibernate不太成熟。当时的EF主要表驱动方式开发,过度依赖edm文件,并且数据层耦 合了模型层,让一些MVC分层用户痛苦不堪。微软从Oxite1项目发展到Oxite2也在这个DAL与MODEL的理不清的关系上做过徘徊,只好在 EDM的基础上直接实现BLL。由于EntityObject模型与ObjectContext耦合,在N层架构构中EntityObject直接提供给 客户端使用的话,那ObjectContext在客户端也会被调用,因此这个时候只能通过DTO对象的方式解决,而毕竟大部分EntityObject是 可以直接传递使用的,而不是一定通过DTO传递。我们看看现在的EF4.0和EF4.1有哪些进步,先来解释一些名词EDM文件EDM是实体数据关系映射的XML文件,不同于Nhibernate每个对象单独映射了一个XML文件。EDM主要有三部分构成 CSDL,SSDL,MSL。CSDL表面的是实体数据模型结构,SSDL表示对应的数据存储的架构,CSDL实体与SSDL数据结构的关系通过MSL映 射实现。EDM是通过ADO.NET 实体数据模型生成的生成EDM文件的方式有两种,一种基于是数据库,一种是创建空EDM模型。前者就是后面要提到的DataBase First方式,后者是Model First方式。 针对创建好的EDM模型最终要生成代码,生成代码的工具不同,生成的代码也不同。看看下面几种生成方式,都于基于EDM模型生成的。ADO.NET 实体数据模型最初EF的方式,实体模型EntityObject与ObjectContext耦合在一起,不适合分层使用。ADO.NET 自跟踪实体生成器分离生成基于POCO的SelfTrackingEnityObject模型和ObjectContext (这种方试即使设置了延迟加载也无法加载关联导航属性,要在使用时手动加载)ADO.NET DbContext Generator分离生成纯POCO模型和轻型DbContext。DbContext较之ObjectContext比较简洁,并且POCO可以充分利用。这就是我为什么选ADO.NET DbContext Generator 的原因,我们再看看EF框架的划分的模式:DataBase FirstModel FirstCode FirstDataBase First传统的表驱动方式创建edm,然后通过edm生成模型和数据层代码。除生成实体模型和自跟踪实现模型,还支持生成纯POCO模型和轻型DbContext。Model First先创建EDM模型,再生成DDL数据库脚本和模型和数据层代码。除生成实体模型和自跟踪实现模型,支持生成纯POCO模型和轻型DbContext。Code First手动创建POCO模型,数据层DbContext及映射关系,通过Database.SetInitializer生成数据库,这种方式较灵活,但是代码工作较多。虽然Code First灵活,但是我们不可能手工去写大量的POCO类和映射关系。如果借助其它ORM工具生成Code First的需要POCO类,为什么试试Model First生成Code First需要的代码呢?本篇选择基于Model First方式+通过ADO.NET DbContext Generator生成基于Code First方式代码,是不是有点概念混乱?但是这种方式基本上和Nhibernate是一致的,而Nhibernate又有着广泛的项目基础。Model First方式主要解决构建模型和EDM映射文件工作。ADO.NET DbContext Generator基于EDM文件生成POCO模型,DbContext代码以及DDL数据库脚本。因为Code First你要自己实现POCO,DbContext的代码,这部分工作如果不借助工具实现代码量还是很大的。做项目不可能像写个Demo用简单的几个类 演示一下就完了,总不能为了演示而学习,最终还是要提高工作效率。这也是为什么我觉得EF已经成熟了决定用于项目的原因。下面就把这个过程简单的走一遍:1.首先创建项目,类库EF.Model,EF.DAL,EF.BLL,控制台EF.Demo。在类库EF.DAL中创建空EDM模型 (为什么要在EF.DAL创建EDM,而不是EF.Model中创建,后面会说明),打开空的EDM模型,我们构建几个实体对象,并映射各个实体间的关系。EDM视图如下:右键属性选择根据模型生成数据库- 生成DemoDB.edmx.sql脚本-打开脚本 右键执行SQL 生成到数据库 2.添加代码生成完成我们的对象设计后,右键EMD属性-添加代码生成项.-选择ADO.NET DbContext Generator生成器 ,这个时候EDMX就变成空模板了,属性生成代码策略被关闭完成后,会自动生成两个tt文件,一个DemoDB.Context.tt (DbContext),一个DemoDB.tt (POCO) 我们将DemoDB.edmx和Demo.tt 两个文件COPY到EF.Model中,并且删除掉EF.DAL中的这两个文件。由于DemoDB.edmx和Demo.tt 两个文件是在EF.DAL创建的,所以移到EF.Model中他们的命名空间还是EF.DAL。不用担心,我们在EF.Model中打开 DemoDB.edmx和Demo.tt两个模板文件,点击保存后,模板会自动修改命名空间为EF.Model。注意了EF.DAL中的 DemoDB.Context.tt模板不要打开保存,否则DbContext的代码会丢失。 这样我们完成了Model和DAL代码的分离工作了。 (DbContext 是EF4.1内容, 另外在VS解决方案的工具里有扩展管理器可直接下载最新的VS扩展插件,通过Library Package Manager的控制台直接添加引用)如果对象修改了,我们只要再保存EDM模板就可以及时更新DemoDB.tt中的对象。而DAL层基本上不需要修改。3. EF.DAL创建通用数据操作类库(仿Nhibernate)IRepository接口:(IOC注入)using System;using System.Collections.Generic;using System.Linq;using System.Text;namespace EF.DALpublic interface IRepositoryT where T : class, new()T Create();T Update(T entity); T Insert(T entity);void Delete(T entity);T Find(params object keyValues);ListT FindAll();RepositoryBase 抽象基类实现 using System;using System.Collections.Generic;using System.Linq;using System.Text;using System.Data;using System.Data.Entity;using EF.DAL;namespace EF.DALpublic abstract class RepositoryBaseT:IRepositoryT where T :class,new()public DbContext context; /提供IOC注入方式接口public RepositoryBase(DemoDBEntities context) this.context = context; /测试用public RepositoryBase() this.context = new DemoDBEntities(); #region IRepositoryT 成员public T Create()return context.SetT().Create();public T Update(T entity)/执行验证业务/context.Entry(entity).GetValidationResult(); if (context.Entry(entity).State = EntityState.Modified) context.SaveChanges();return entity;public T Insert(T entity)context.SetT().Add(entity);context.SaveChanges(); return entity;public void Delete(T entity)context.SetT().Remove(entity);context.SaveChanges();public T Find(params objectkeyValues)return context.SetT().Find(keyValues); public ListT FindAll()return context.SetT().ToList();#endregionIBlogCategoryRepository 接口(IOC注入) using System;using System.Collections.Generic;using System.Linq;using System.Text;using EF.Model;namespace EF.DALpublic interface IBlogCategoryRepository:IRepositoryBlogCategoryBlogArticleRepository实现 using System;using System.Collections.Generic;using System.Linq;using System.Text;using EF.Model;namespace EF.DALpublic class BlogArticleRepository:RepositoryBaseBlogArticle,IBlogArticleRepository看看后面两个具体数据操作类的代码极其简单,这就是EF4.0 之后的泛型的优点 ,可以使代码尽量的简洁。 4.EF.BLL层简单的实现一下业务BlogCategoryService 实现关联表操作(添加一个BlogCategory分类,并且在这个分类下增加一个BlogArticle文章)using System;using System.Collections.Generic;using System.Linq;using System.Text;using EF.DAL;using EF.Model;namespace EF.BLLpublic class BlogCategoryService IRepositoryBlogCategory repositoryCategory;IRepositoryBlogArticlerepositoryArticle;public BlogCategoryService(IRepositoryBlogCategoryrepositoryCategory,IRepositoryBlogArticle repositoryArticle) this.repositoryCategory = repositoryCategory;this.repositoryArticle = repositoryArticle;public BlogCategoryService() this.repositoryCategory = new BlogCategoryRepository();this.repositoryArticle = new BlogArticleRepository(); public BlogCategory CreateBlogCategory()return repositoryCategory.Create(); public BlogArticle CreateBlogArticle()return repositoryArticle.Create();public BlogCategory Insert(BlogCategory entity)return repositoryCategory.Insert(entity);public BlogCategory Update(BlogCategory entity)return repositoryCategory.Update(entity);public void Delete(BlogCategory entity) repositoryCategory.Delete(entity);5.EF.Model测试导航属性关联操作(同时往两张表插入记录) using System;using System.Collections.Generic;using System.Linq;using System.Text;using EF.Model;using EF.BLL;namespace EF.Demo class Program static void Main(string args) BlogCategoryService service=new BlogCategoryService();/创建博文分类BlogCategory cate = service.CreateBlogCategory();cate.CateName = EF分类标签;/创建一篇博文BlogArticle arti = service.CreateBlogArticle(); arti.Title = EF进化论; arti.Content = EF测试内容; /博文加到博文分类cate.BlogArticle.Add(arti);/更新 service.Insert(cate);Console.ReadLine(); 6.结果 通过Model First的方式+ADO.NET DbContext Generator生成器 实现Code First方式业务(EDMX通过DbContext构造注入其中),到达Hibernate的效果。EDMX相当于Hibernate 对象模型XML映射文件,POCO相当于Hibernate对象模型(virtual实现关联导航加载),DbContext通过泛型构建 IRepository数据操作类。之前看到相关测试,微软的EF ADO.NET 测试效率高出Hibernate 30%左右,不知道是不是真的-_-|。 另外提一点 DbContext 可以转换为ObjectContext,用Refletor反编译看到是通过一个中间InternalContext实现的实现代码: ObjectContext context = (IObjectContextAdapter) DbContext).ObjectContext;如果不想直接加载导航属性数据,你可以在DbContext的构造函数禁用延迟加载。/ /此代码是根据模板生成的。/手动更改此文件可能会导致应用程序中发生异常行为。/如果重新生成代码,则将覆盖对此文件的手动更改。/namespace EF.DALusing System;using System.Data.Entity;using System.Data.Entity.Infrastructur

温馨提示

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

评论

0/150

提交评论