Entity Framework学习笔记(四)----Linq查询(1)
请注明转载地址:http://www.cnblogs.com/arhat
从本章开始,老魏就介绍一下Entity Framework使用Linq来查询数据,也就是Linq To Entity。其实在Entity Framework中提供了3中查询方式,除了使用Linq还有Lambda表达式,EQL语句,其中EQL是用于复杂的查询,当Linq无法胜任的时候就要使用了EQL了,当然也可以使用存储过程。废话不多说,开始本章的内容。
在本章中查询的依然是Student和Clazz两张表,主要涉及到是单表查询和一个关联查询,对于多对多查询将在下一章讲解。
Demo1:查询一下全部学生的信息。
原生SQL:
select * from Student
Linq:
DAL.SchoolContext context = new DAL.SchoolContext(); var query = from student in context.Student select student; foreach (var student in query) { Console.WriteLine(student.SId + "----" + student.SName + "----" + student.SAge + "----" + student.SMail); }
翻译SQL:
SELECT [Extent1].[SId] AS [SId], [Extent1].[SName] AS [SName], [Extent1].[SAge] AS [SAge], [Extent1].[SMail] AS [SMail], [Extent1].[CId] AS [CId] FROM [dbo].[Student] AS [Extent1]
结果:
大家看到这个Linq翻译的SQL语句还是非常不错的。并没有额外的开支。
Demo2:查询一下全部学生的信息,并显示学生所在的班级信息。
原生SQL:
select * from Student as a inner join Clazz as b on a.CId= b.CId
Linq:
DAL.SchoolContext context = new DAL.SchoolContext(); var query = from student in context.Student select student; foreach (var student in query) { Console.WriteLine(student.SId + "----" + student.SName + "----" + student.SAge + "----" + student.SMail+"----班级信息:"+student.Clazz.CId+"----"+student.Clazz.CName); }
翻译SQL:这个老魏就不贴出来了,太长了,大家可以看看
从图上可以看出,这个Linq执行的时候是先把学生全部查询出来,然后在根据Student.CId字段分别取得到Clazz信息,如果我们的信息有100000条数据的话,可想而知了。虽然牺牲了性能,但却换来了编程上的方便。如果大家思考一下老魏的这程序,会发现项目中没有这么干的,如果数据多的请情况下肯定要使用分页的,如果使用分页的话,那么产生的SQL查询次数肯定要比全部的少很多,的确如此,但是还是多了。其实这也没有办法,在所有的ORM框架中使用懒加载的时候都是如此,牺牲效率。
在这里呢,Entity Framework是默认启用懒加载机制的,所谓的懒加载老魏在NHibernate中已经讲解过了,其实就是在使用的时候在向SQL发送查询指令。这里我们通过Student的Clazz导航属性来得到班级的信息。当然如果我们不需班级信息的话,那么就不会向SQL发送指令了。
结果:
此时呢,我们在换一种写法,不使用懒加载,而是通过Linq的join语句来试试看看。
Linq:
DAL.SchoolContext context = new DAL.SchoolContext(); var query = from student in context.Student join clazz in context.Clazz on student.CId equals clazz.CId select new { SName =student.SName, CName = clazz.CName }; foreach (var record in query)
{ Console.WriteLine(record.SName + "----" + record.CName); }
翻译SQL:
SELECT [Extent2].[CId] AS [CId], [Extent1].[SName] AS [SName], [Extent2].[CName] AS [CName] FROM [dbo].[Student] AS [Extent1] INNER JOIN [dbo].[Clazz] AS [Extent2] ON [Extent1].[CId] = [Extent2].[CId]
这个时候,我们发现了,这个Linq生成的SQL语句还真是我们想要的语句,直接把我们想要的东西通过inner join来查询出来了,可是随之的问题有出现了,为什么呢?如果我们要分层的开发项目,这段代码应该是在DAL层中的,但是此时我们用了匿名对象来保存我们的查询结果,而匿名对象是不能跨域访问的,这该怎么办呢?这里呢老魏也没想到好的方法,但是提供两个参考
1,使用扩展防方法给IEnumable<T>扩展一个方法,优点复杂老魏不喜欢
2,使用.net4.0的dynamic关键字,虽然可以实现,但是没有智能提示,不过勉强接受。
static void Main(string[] args)
{ var query = Test(); foreach (dynamic d in query) { Console.WriteLine(d.SName + "----" + d.CName); } } public static dynamic Test()
{ DAL.SchoolContext context = new DAL.SchoolContext(); var query = from student in context.Student join clazz in context.Clazz on student.CId equals clazz.CId select new
{ SName = student.SName, CName = clazz.CName
}; return query as dynamic; }
谁有好的方法可以共享一下,老魏这里实在是想不到一个好的方法了。好了,不在这个问题上过多的纠缠了。
可能看到这里我们有会忽然间想到,如果我们不查询部分字段那又是什么情况呢?
Linq:
DAL.SchoolContext context = new DAL.SchoolContext(); var query = from student in context.Student join clazz in context.Clazz on student.CId equals clazz.CId into Rows from row in Rows select row; foreach (var row in query)
{ Console.WriteLine(row.CName); }
当我们写到row.的时候,会发现row这个对象中只有CId,CName和一个奇怪的Students对象。这是怎么回事啊。我们通过这条Linq语句生成的SQL语句可以看出端倪。
翻译SQL:
SELECT [Extent2].[CId] AS [CId], [Extent2].[CName] AS [CName] FROM [dbo].[Student] AS [Extent1] INNER JOIN [dbo].[Clazz] AS [Extent2] ON [Extent1].[CId] = [Extent2].[CId]
大家从翻译的SQL中可以看到最终查询的结果是是吧Clazz的字段全部查询出来了,查询结果如下:
每一个课程都有一个Student对象,那么当然在Clazz中有一个Students对象。只有当我们查询Student对象的时候,才会向SQL依次的发送指令。其实还是懒加载,。看到这里我们是不是相到既然这样我们可以关闭懒加载啊,是的,可以的没有任何的问题,我们在上面的代码中我们加入一句话。
DAL.SchoolContext context = new DAL.SchoolContext(); //取消懒加载 context.Configuration.LazyLoadingEnabled = false; var query = from student in context.Student join clazz in context.Clazz on student.CId equals clazz.CId into Rows from row in Rows select row; foreach (var row in query) { Console.WriteLine(row.CName+",次班级的人数:"+row.Students.Count); }
运行结果:
发现人数打印出来是0,因为我们取消了懒加载,所以在使用到了Student的时候不会向SQL发送指令,就不会查询人数了,但是从上图中其实我们看出来总的记录加起来还是人数哦!
本章就先到这里吧,虽然本章只涉及到了2个查询,但还是有收货的,值得在我们学习Entity Framework的时候多深入的思考一下。
Entity Framework学习笔记(四)----Linq查询(1)的更多相关文章
- Entity Framework学习笔记(五)----Linq查询(2)---贪婪加载
请注明转载地址:http://www.cnblogs.com/arhat 在上一章中,我们使用了Linq对Entity Framework进行了一个查询,但是通过学习我们却发现了懒加载给我来的性能上的 ...
- 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 学习笔记(2)
上期回顾:Entity Framework 学习笔记(1) Entity Framework最主要的东西,就是自己创建的.继承于DbContext的类: /// <summary> /// ...
- Entity Framework学习笔记(六)----使用Lambda查询Entity Framework(1)
请注明转载地址:http://www.cnblogs.com/arhat 在前几章中,老魏一直使用Linq来查询Entity Framework.但是老魏感觉,如果使用Linq的话,那么Linq的返回 ...
- Entity Framework学习笔记——错误汇总
之前的小项目做完了,到了总结经验和更新学习笔记的时间了.开始正题之前先啰嗦一下,对之前的学习目标进行一个调整:“根据代码生成表”与“生成数据库脚本和变更脚本”合并为“Code First模式日常使用篇 ...
- Entity Framework学习笔记(二)----CRUD(1)
请注明转载地址:http://www.cnblogs.com/arhat 这篇文章老魏和大家分享一下Entity Framework的CRUD操作,在这之前呢,老魏先说一下老魏对EF的一个整体的认识, ...
- Entity Framework 学习笔记
1.自定义数据库链接字符串上下文 public class PetDbContext : DbContext { public PetDbContext() : base("name=Dem ...
- Entity Framework学习笔记——配置EF
初次使用Entity Framework(以下简称EF),为了避免很快忘记,决定开日志记录学习过程和遇到的问题.因为项目比较小,只会用到EF的一些基本功能,因此先在此处制定一个学习目标:1. 配置EF ...
随机推荐
- node.js 快速体验
对于一个从事js的工作人员,怎么能不知道node.js呢! 一.安装node.js 在window上安装,http://nodejs.org上的windows installer 下载安装,在安装过程 ...
- 【MySQL】InnoDB引擎ibdata文件损坏/删除后使用frm和ibd文件恢复数据
参考:http://my.oschina.net/sansom/blog/179116 参考:http://www.jb51.net/article/43282.htm 注意!此方法只适用于innod ...
- 【python】基础
[字符串]前后引号必须要匹配,相关函数int(),float(),str(),repr(),format(),还有切片运算符 a = 'text' 单引号指定的字符串必须在一个逻辑 ...
- ASP.NET的SEO:使用.ashx文件——排除重复内容
本系列目录 不同的链接指向的页面如果具有大量相同的内容,这种现象就会被称为"重复内容",如果一个网站的重复内容很多,搜索引擎就会认为这个网站的价值不高.所以我们应尽量避免各种重复内 ...
- Linux内核中ioremap映射的透彻理解
几乎每一种外设都是通过读写设备上的寄存器来进行的,通常包括控制寄存器.状态寄存器和数据寄存器三大类,外设的寄存器通常被连续地编址.根据CPU体系结构的不同,CPU对IO端口的编址方式有两种: (1)I ...
- how to extract and decrypt WeChat EnMicromsg.db on Android phone
One of my friend came to me with an Android phone. She saild somehting wrong with the hardware of he ...
- Android WebRTC 音视频开发总结(二)-- webrtcdemo介绍
这节主要介绍WebRTCDemo的结构,以此来简单了解WebRTC的调用流程,转载请说明出处(博客园RTC.Blacker) 1.先看WebRTCDemo的代码结构,如下图: 2.WebRTCDemo ...
- 二十一、contextMap中放的常用数据
二十一.contextMap中放的常用数据 request:请求范围的数据.即ServletRequest中的那个Map parameters:请求参数的数据.即request.getParamete ...
- JavaScript常用标签和方法总结
什么是javascript? (1) JavaScript是一种基于对象(Object)和事件驱动(Event Driven)并具有安全性能的 脚本语言. (2) JavaScript是由Nets ...
- jQuery通过jquery.form.js插件使用AJAX提交Form表单
我简单使用了一下,jQuery Form插件有一下优点: 1.支持提交前验证. 2.支持提交后回调. 3.采用AJAX方式,有很好的用户体验 4.提交方式是灵活.只要指定要提交的form ID即可. ...