Entity Framework学习笔记(二)----CRUD(1)
请注明转载地址:http://www.cnblogs.com/arhat
这篇文章老魏和大家分享一下Entity Framework的CRUD操作,在这之前呢,老魏先说一下老魏对EF的一个整体的认识,当然如果有不对的地方希望大家能够提出来,我们来一起的讨论一下。
老魏在经历了NHibernate这个ORM框架之后接触了EF这个在.NET平台上迟来的自家的ORM框架,从整体上看,其实这两个ORM框架的思想倒是很多是一样的,但是在使用了EF后,再发现有很多的操作比起NHibernate要强了不少,但是同时也暴露出了很多的问题,这些问题是老魏目前比较头疼的问题,到现在都没找到一个合适的解决方法,只能是希望EF在后续的版本中能够解决这些问题。
在EF查询的时候,其中有一个最让人蛋疼的问题就是不能够把匿名对象交给其他域访问,也就是匿名对象跨域访问的问题,当然在网络上有一些解决方法,但是老魏老是感觉不是很好,在老赵的一片文章中虽然提供了一个比较不错的方法,但是使用起来时比较的麻烦的,哎,只能说到现在老魏也是在头疼这个问题。
在EF中如果使用linq的分组的时候,需要用到两次的foreach循环,而且更让人蛋疼的设计是竟然在group的时候懒加载竟然不能使用,如果使用的话竟然报了一个“There is already an open datareader accociated width this Connection which must be closed first”的错误,很是无语啊。当然这个问题很有可能和数据的设置有关系,在后面的章节中老魏会来讨论一下这个问题。
同时在EF中,微软给出了两个查询的方案,一个是使用Linq to Entity另外一个是EQL。当然看到这里可能大家会迷糊(老魏也曾迷惑过),那么在使用EF的时候是使用linq呢还是EQL呢?其实这个问题我们很好回答,迷糊的原因是微软提供了多个解决方案而已,用的时候根据个人的爱好选择使用。一般情况下,如果遇到复杂SQL语句,ling无法解决的时候就需要EQL了。老魏认为微软太为程序员着想了,弄的程序员都得学习,其实这点就不如NHibernate了,只提供一个HQL语句,用不用就看你了。所以说啊,微软有时候这好人做的确实是有点过了。
不过怎么说呢,在使用EF的时候说实在的的确要比NHibernate要方便的多了,不用再配那么多的映射文件了。
好了,上面就是老魏对EF的人是,如果各位网友有更好的建议可以为老魏提出来。下面我们就开始今天的章节吧。
接着上一节内容,在上一节中我们对School这个数据进行了EF Db Fist了。那么现在我们就要使用这个EF来操作这两个表了,当然在后面的章节中老魏会添加一张Course(课程)表用来学习查询的相关的学习。
首先测试,虽然我们建立了三层的架构,但是为了测试方便我们在主项目Test中添加对DAL和Model的引用。
首先呢,我们为课程添加记录,在Program.cs文件中我们更改代码如下:
static void Main(string[] args) { //上下文对象 DAL.SchoolContext context = new DAL.SchoolContext(); //创建一个clazz对象 Model.Clazz clazz = new Model.Clazz() { CName="测试课程" }; //把clazz加入到ObjectSet中,但是此时并没有插入到数据库 context.Clazz.AddObject(clazz); //更新数据库,这时才真正的吧clazz加入到了数据中 context.SaveChanges(); }
那么现在我们执行一下,发现没有任何的问题,打开数据库查看一下:
看来我们正确的把数据插入到数据库中。对于上面的代码老魏得解释一下,因为有很多东西并不是我们所了解的,大部分的代码都是有EF给我生成的。
首先是SchoolContext这东西。这个东西是至关重要的一个东西了,称之为数据上下文对象。我们操作数据库就是靠这个东西的。从SchoolContext的继承关系上,我们知道它继承了ObjectContext(对象上下文)。其实这点才是老魏迷糊的地方,记得官方说的EF6默认使用的DbContext,可这里VS2010使用的ObjectContext了,老魏没有找到原因,还有一个可能就是老魏使用的是MySql数据,难道老魏装的MySql Connector不支持EF6吗?不可能啊,官方说的是可以支持的。其实最后老魏发现,原来老魏用的T4模板中是用的ObjectContext的。不过无所谓了,原理都一样的,那我们先使用ObjectContext吧。到后面的章节中老魏得想办法用VS2013的,这样就回跟上了。
ObjectContext是Entity Framework封装了数据库访问的上下文,以及实体的映射关系元数据信息等。EF帮我们封装好了这么一个统一的接口。让我们所有的操作都只通过这个一个实体上下文就可以实现了增删查改等所有对应数据库的操作。我们查看一下ObjectContext的定义:
不知道大家从图上看到了什么,红色部分能够帮我们了解ObjectContext的本质是什么,从红色的部分知道了ObjectContext为什么能够帮我们连接数据库了,其实还是通过connectionString,DbConnectgion这些传统的ADO.NET的知识来连接的。但是ObjectContext是不可能只做这写事,如果是这样的话那么EF也就太弱了吧(哈哈)。当我们使用Model First的时候,为什么为自动的创建数据?原因大家已经看到了,在ObjectContext中有一个CreateDataBase的方法,同时还有一个CreateObject的方法,这个方法我想就不需要解释了吧。
需要注意的是黄色的部分才是比较重要的地方,在我们的SchoolContext中我们发现有这样的属性:
public ObjectSet<Model.Clazz> Clazz { get { return _clazz ?? (_clazz = CreateObjectSet<Model.Clazz>("Clazz")); } }
而这个属性是ObjectSet类型的,那么ObjectSet有一个是什么东东呢?根据微软的解释“ObjectSet表示模型的实体集”。那么很显然了ObjectSet是一个集合。当然了ObjectSet不仅仅是一个实体集而已了,它同时提供了对实体集的用于执行创建、读取、更新和删除操作,这也就是我们context.Clazz.AddObject(clazz)通过这句话来添加实体对象了。
这个是ObjectSet的定义,我会发现它的确是提供了很多方法能够操作实体集。其实说到这里呢,各位不知道有没有一些发现呢?通过对比的话,我们能够更简单易懂的理解ObjectContext和ObjectSet了。下面老魏来画张图来说明这两个对象和数据库之间的关系。
从图上我们可以这样来理解,DataBase(数据库)对应一个ObjectContext(DbContext),只不过ObjectContext(DbContext)封装了一些列操作数据的方法,功能强大了。然而DataBase中的每个表都可以认为是ObjectSet对象,一个表就是一个ObjectSet,其实很容易的理解,一个表有多个记录,每个记录就是一个实体,而这些实体是不是存放在表中的而是ObjectSet中的。同样的,ObjectSet不仅仅只是用来存储实体的,还提供操作实体的方法,功能也强大啊!
通过上面的解释,老魏相信大家应该对ObjectConext(DbContext)和ObjectSet有一些了解了吧,希望能够帮助大家。
好了,这两个对象已经给家讲过了,下面就继续本章的内容。刚才我们只是在clazz表中添加了一条记录,删除和编辑我们来做一下。
更改一下Program.cs的代码,我们来删除一条记录:
static void Main(string[] args) { //上下文对象 DAL.SchoolContext context = new DAL.SchoolContext(); //得到一个clazz对象 Model.Clazz clazz = context.Clazz.Where<Model.Clazz>(c => c.CId == 12).FirstOrDefault<Model.Clazz>(); //把clazz从ObjectSet中删除,并咩有真正的删除 context.Clazz.DeleteObject(clazz); //更新数据库,这时才真正的吧clazz从数据库中删除 context.SaveChanges(); }
这里老魏不得不说了,在删除的时候EF要求先去查询一下这个数然后才能删除,这样的话我们就回打开两次数据库了,从性能上说是非常不好的,但是微软的这种考虑是值得思考的,在项目中我们删除数据的时候很有可能是判断这条数据存不存在,如果存在则删除。其实这种需求是存在。但是如果不想这样先查询在删除的话,也是可以的,这个问题将在下一章节在阐述吧。
同理,我们再更改一下Program.cs来编辑一条记录吧,从上面的删除的过程我们就可以推测出肯定也是先查询然后再更改的。
static void Main(string[] args) { //上下文对象 DAL.SchoolContext context = new DAL.SchoolContext(); //得到一个clazz对象 Model.Clazz clazz = context.Clazz.Where<Model.Clazz>(c => c.CId == 11).FirstOrDefault<Model.Clazz>(); //更新CName值,并咩有真正的在数据中更新 clazz.CName = "ASP.NET MVC学习班"; //更新数据库,这时才真正的吧clazz从数据库中更新 context.SaveChanges(); }
到此呢,本章基本就要结束了,在实现了CRUD之后呢,值得我们思考的是EF虽然给我们带来了方便,但是底层的东西还是要会的,当然老魏值得是ADO.NET。其实在项目中还是ADO.NET用的居多啊。
不知道看过这章的网友有没有收获呢,如果有的话老魏是非常高兴的。在提供我自己的同时也帮到了大家,真是应了那句话”独乐了不如众乐乐”。
Entity Framework学习笔记(二)----CRUD(1)的更多相关文章
- Entity Framework学习笔记(三)----CRUD(2)
请注明转载地址:http://www.cnblogs.com/arhat 昨天晚上老魏配的机器终于到了,可是拿回来之后什么都组装好了,唯独差一个非常重要的组件"电源线",老魏那个汗 ...
- Entity Framework 学习笔记(2)
上期回顾:Entity Framework 学习笔记(1) Entity Framework最主要的东西,就是自己创建的.继承于DbContext的类: /// <summary> /// ...
- Entity Framework学习笔记
原文地址:http://www.cnblogs.com/frankofgdc/p/3600090.html Entity Framework学习笔记——错误汇总 之前的小项目做完了,到了总结经验和 ...
- ADO.NET Entity Framework学习笔记(3)ObjectContext
ADO.NET Entity Framework学习笔记(3)ObjectContext对象[转] 说明 ObjectContext提供了管理数据的功能 Context操作数据 AddObject ...
- Entity Framework 学习笔记(二)之数据模型 Model 使用过程
Entity Framework 数据模型 Model 创建的使用: 开发环境:VS2012 数据库:SQL Server 2008 Entity Framework 版本:6.12 下面是新建的 ...
- Entity Framework学习笔记(一)
请注明转载地址:http://www.cnblogs.com/arhat 哈哈!老魏回来了,4月份的内容开始更新了,由于3月份时间都在做项目,没有时间写了,那么4月份老魏会尽可能的多写点东西的.那么4 ...
- Entity Framework 学习笔记
1.自定义数据库链接字符串上下文 public class PetDbContext : DbContext { public PetDbContext() : base("name=Dem ...
- Entity Framework学习笔记——错误汇总
之前的小项目做完了,到了总结经验和更新学习笔记的时间了.开始正题之前先啰嗦一下,对之前的学习目标进行一个调整:“根据代码生成表”与“生成数据库脚本和变更脚本”合并为“Code First模式日常使用篇 ...
- Entity Framework学习笔记——记一个错误解决方式及思路
继续之前设定的学习目标前,先来一篇小小的外篇.按照第一篇里的配置方式配置好的工程前两天还能正常工作,昨天却突然无法通过Add-Migration命令进行数据库的升级.错误信息如下: System.Da ...
随机推荐
- 在C++中调用DLL中的函数 (2)
应用程序使用DLL可以采用两种方式: 一种是隐式链接,另一种是显式链接.在使用DLL之前首先要知道DLL中函数的结构信息. Visual C++6.0在VC\bin目录下提供了一个名为Dumpbin. ...
- 使用ffmpeg快速生成视频截图
1 ffmpeg -i input.mkv -ss 00:10:00 -f image2 output.jpg 但是这个命令会花费相当长的时间. 对一个清晰的或者较大的视频文件进行操作, 会花费半分钟 ...
- 父窗口调用iframe子窗口方法
一.父窗口调用iframe子窗口方法 1.HTML语法:<iframe name="myFrame" src="child.html"></i ...
- 使用py2exe打包你的py程序
软件环境:python3.3.4 + PyQt5 使用py2exe打包写好的py文件,过程如下: 在你要打包的代码文件(比如sample.py)的同文件夹建立一个python代码文件(比如setup. ...
- 使用扩展方法(this 扩展类型)
namespace ConsoleApp_UseExtendWays{ class Program { static void Main(string[] args) { Student s = ne ...
- Java移位运算
java中移位运算符有三种“<<”.“>>”.“>>>”,没有“<<<”运算符. “<<”运算符将二进制位进行左移,低位用0来填 ...
- import static与import的区别
import static(静态导入)是JDK1.5中的新特性,一般我们导入一个类都用 import com.....ClassName;而静态导入是这样:import static com..... ...
- javaSE第二十一天
第二十一天 276 1:字符流(掌握) 276 (1)字节流操作中文数据不是特别的方便,所以就出现了转换流. 276 (2)转换流其实是一个字符流 276 1:InputStr ...
- mysql快速上手1
mysql简介 1.什么是数据库 ? 数据库(Database)是按照数据结构来组织.存储和管理数据的仓库,它产生于距今六十多年前,随着信息技术和市场的发展,特别是二十世纪九十年代以后,数据管理不再仅 ...
- 极速地将git项目部署到SAE的svn服务器上
本文最初发布于我的个人博客:http://jerryzou.com/posts/gitForSAE/ 我花了一些时间自己写了一个能够极速地将一个git项目部署到SAE的svn服务器上的脚本.代码不是复 ...