请注明转载地址:http://www.cnblogs.com/arhat

从本章开始,老魏就介绍一下Entity Framework使用Linq来查询数据,也就是Linq To Entity。其实在Entity Framework中提供了3中查询方式,除了使用Linq还有Lambda表达式,EQL语句,其中EQL是用于复杂的查询,当Linq无法胜任的时候就要使用了EQL了,当然也可以使用存储过程。废话不多说,开始本章的内容。

在本章中查询的依然是Student和Clazz两张表,主要涉及到是单表查询和一个关联查询,对于多对多查询将在下一章讲解。

Demo1:查询一下全部学生的信息。

原生SQL:

  1. select * from Student

Linq:

  1. DAL.SchoolContext context = new DAL.SchoolContext();
  2.  
  3. var query = from student in context.Student
  4.  
  5. select student;
  6.  
  7. foreach (var student in query)
  8.  
  9. {
  10.  
  11. Console.WriteLine(student.SId + "----" + student.SName + "----" + student.SAge + "----" + student.SMail);
  12.  
  13. }

翻译SQL:

  1. SELECT
  2.  
  3. [Extent1].[SId] AS [SId],
  4.  
  5. [Extent1].[SName] AS [SName],
  6.  
  7. [Extent1].[SAge] AS [SAge],
  8.  
  9. [Extent1].[SMail] AS [SMail],
  10.  
  11. [Extent1].[CId] AS [CId]
  12.  
  13. FROM [dbo].[Student] AS [Extent1]

结果:

大家看到这个Linq翻译的SQL语句还是非常不错的。并没有额外的开支。

Demo2:查询一下全部学生的信息,并显示学生所在的班级信息。

原生SQL:

  1. select * from Student as a inner join Clazz as b on a.CId= b.CId

Linq:

  1. DAL.SchoolContext context = new DAL.SchoolContext();
  2.  
  3. var query = from student in context.Student
  4.  
  5. select student;
  6.  
  7. foreach (var student in query)
  8.  
  9. {
  10.  
  11. Console.WriteLine(student.SId + "----" + student.SName + "----" + student.SAge + "----" + student.SMail+"----班级信息:"+student.Clazz.CId+"----"+student.Clazz.CName);
  12.  
  13. }

翻译SQL:这个老魏就不贴出来了,太长了,大家可以看看

从图上可以看出,这个Linq执行的时候是先把学生全部查询出来,然后在根据Student.CId字段分别取得到Clazz信息,如果我们的信息有100000条数据的话,可想而知了。虽然牺牲了性能,但却换来了编程上的方便。如果大家思考一下老魏的这程序,会发现项目中没有这么干的,如果数据多的请情况下肯定要使用分页的,如果使用分页的话,那么产生的SQL查询次数肯定要比全部的少很多,的确如此,但是还是多了。其实这也没有办法,在所有的ORM框架中使用懒加载的时候都是如此,牺牲效率。

在这里呢,Entity Framework是默认启用懒加载机制的,所谓的懒加载老魏在NHibernate中已经讲解过了,其实就是在使用的时候在向SQL发送查询指令。这里我们通过Student的Clazz导航属性来得到班级的信息。当然如果我们不需班级信息的话,那么就不会向SQL发送指令了。

结果:

此时呢,我们在换一种写法,不使用懒加载,而是通过Linq的join语句来试试看看。

Linq:

  1. DAL.SchoolContext context = new DAL.SchoolContext();
  2.  
  3. var query = from student in context.Student
  4.  
  5. join clazz in context.Clazz
  6.  
  7. on student.CId equals clazz.CId
  8.  
  9. select new
  10.  
  11. {
  12.  
  13. SName =student.SName,
  14.  
  15. CName = clazz.CName
  16.  
  17. };
  18.  
  19. foreach (var record in query)
  20. {
  21.  
  22. Console.WriteLine(record.SName + "----" + record.CName);
  23.  
  24. }

翻译SQL:

  1. SELECT
  2.  
  3. [Extent2].[CId] AS [CId],
  4.  
  5. [Extent1].[SName] AS [SName],
  6.  
  7. [Extent2].[CName] AS [CName]
  8.  
  9. FROM [dbo].[Student] AS [Extent1]
  10.  
  11. INNER JOIN [dbo].[Clazz] AS [Extent2] ON [Extent1].[CId] = [Extent2].[CId]

这个时候,我们发现了,这个Linq生成的SQL语句还真是我们想要的语句,直接把我们想要的东西通过inner join来查询出来了,可是随之的问题有出现了,为什么呢?如果我们要分层的开发项目,这段代码应该是在DAL层中的,但是此时我们用了匿名对象来保存我们的查询结果,而匿名对象是不能跨域访问的,这该怎么办呢?这里呢老魏也没想到好的方法,但是提供两个参考

1,使用扩展防方法给IEnumable<T>扩展一个方法,优点复杂老魏不喜欢

2,使用.net4.0的dynamic关键字,虽然可以实现,但是没有智能提示,不过勉强接受。

  1. static void Main(string[] args)
  2. {
  3.  
  4. var query = Test();
  5.  
  6. foreach (dynamic d in query)
  7.  
  8. {
  9.  
  10. Console.WriteLine(d.SName + "----" + d.CName);
  11.  
  12. }
  13.  
  14. }
  15.  
  16. public static dynamic Test()
  17. {
  18.  
  19. DAL.SchoolContext context = new DAL.SchoolContext();
  20.  
  21. var query = from student in context.Student
  22.  
  23. join clazz in context.Clazz
  24.  
  25. on student.CId equals clazz.CId
  26.  
  27. select new
  28. {
  29.  
  30. SName = student.SName,
  31.  
  32. CName = clazz.CName
  33. };
  34.  
  35. return query as dynamic;
  36.  
  37. }

谁有好的方法可以共享一下,老魏这里实在是想不到一个好的方法了。好了,不在这个问题上过多的纠缠了。

可能看到这里我们有会忽然间想到,如果我们不查询部分字段那又是什么情况呢?

Linq:

  1. DAL.SchoolContext context = new DAL.SchoolContext();
  2.  
  3. var query = from student in context.Student
  4.  
  5. join clazz in context.Clazz
  6.  
  7. on student.CId equals clazz.CId
  8.  
  9. into Rows
  10.  
  11. from row in Rows
  12.  
  13. select row;
  14.  
  15. foreach (var row in query)
  16. {
  17.  
  18. Console.WriteLine(row.CName);
  19.  
  20. }

当我们写到row.的时候,会发现row这个对象中只有CId,CName和一个奇怪的Students对象。这是怎么回事啊。我们通过这条Linq语句生成的SQL语句可以看出端倪。

翻译SQL:

  1. SELECT
  2.  
  3. [Extent2].[CId] AS [CId],
  4.  
  5. [Extent2].[CName] AS [CName]
  6.  
  7. FROM [dbo].[Student] AS [Extent1]
  8.  
  9. INNER JOIN [dbo].[Clazz] AS [Extent2] ON [Extent1].[CId] = [Extent2].[CId]

大家从翻译的SQL中可以看到最终查询的结果是是吧Clazz的字段全部查询出来了,查询结果如下:

每一个课程都有一个Student对象,那么当然在Clazz中有一个Students对象。只有当我们查询Student对象的时候,才会向SQL依次的发送指令。其实还是懒加载,。看到这里我们是不是相到既然这样我们可以关闭懒加载啊,是的,可以的没有任何的问题,我们在上面的代码中我们加入一句话。

  1. DAL.SchoolContext context = new DAL.SchoolContext();
  2.  
  3. //取消懒加载
  4.  
  5. context.Configuration.LazyLoadingEnabled = false;
  6.  
  7. var query = from student in context.Student
  8.  
  9. join clazz in context.Clazz
  10.  
  11. on student.CId equals clazz.CId
  12.  
  13. into Rows
  14.  
  15. from row in Rows
  16.  
  17. select row;
  18.  
  19. foreach (var row in query)
  20.  
  21. {
  22.  
  23. Console.WriteLine(row.CName+",次班级的人数:"+row.Students.Count);
  24.  
  25. }

运行结果:

发现人数打印出来是0,因为我们取消了懒加载,所以在使用到了Student的时候不会向SQL发送指令,就不会查询人数了,但是从上图中其实我们看出来总的记录加起来还是人数哦!

本章就先到这里吧,虽然本章只涉及到了2个查询,但还是有收货的,值得在我们学习Entity Framework的时候多深入的思考一下。

Entity Framework学习笔记(四)----Linq查询(1)的更多相关文章

  1. Entity Framework学习笔记(五)----Linq查询(2)---贪婪加载

    请注明转载地址:http://www.cnblogs.com/arhat 在上一章中,我们使用了Linq对Entity Framework进行了一个查询,但是通过学习我们却发现了懒加载给我来的性能上的 ...

  2. Entity Framework学习笔记

    原文地址:http://www.cnblogs.com/frankofgdc/p/3600090.html Entity Framework学习笔记——错误汇总   之前的小项目做完了,到了总结经验和 ...

  3. ADO.NET Entity Framework学习笔记(3)ObjectContext

    ADO.NET Entity Framework学习笔记(3)ObjectContext对象[转]   说明 ObjectContext提供了管理数据的功能 Context操作数据 AddObject ...

  4. Entity Framework 学习笔记(2)

    上期回顾:Entity Framework 学习笔记(1) Entity Framework最主要的东西,就是自己创建的.继承于DbContext的类: /// <summary> /// ...

  5. Entity Framework学习笔记(六)----使用Lambda查询Entity Framework(1)

    请注明转载地址:http://www.cnblogs.com/arhat 在前几章中,老魏一直使用Linq来查询Entity Framework.但是老魏感觉,如果使用Linq的话,那么Linq的返回 ...

  6. Entity Framework学习笔记——错误汇总

    之前的小项目做完了,到了总结经验和更新学习笔记的时间了.开始正题之前先啰嗦一下,对之前的学习目标进行一个调整:“根据代码生成表”与“生成数据库脚本和变更脚本”合并为“Code First模式日常使用篇 ...

  7. Entity Framework学习笔记(二)----CRUD(1)

    请注明转载地址:http://www.cnblogs.com/arhat 这篇文章老魏和大家分享一下Entity Framework的CRUD操作,在这之前呢,老魏先说一下老魏对EF的一个整体的认识, ...

  8. Entity Framework 学习笔记

    1.自定义数据库链接字符串上下文 public class PetDbContext : DbContext { public PetDbContext() : base("name=Dem ...

  9. Entity Framework学习笔记——配置EF

    初次使用Entity Framework(以下简称EF),为了避免很快忘记,决定开日志记录学习过程和遇到的问题.因为项目比较小,只会用到EF的一些基本功能,因此先在此处制定一个学习目标:1. 配置EF ...

随机推荐

  1. 堆栈的实现(c语言)

    #include <stdio.h> #include <stdlib.h> #include <stdbool.h> #define EmptyTOS (-1) ...

  2. Android各个文件夹对应的分辨率?

  3. asp.net常用字符串函数

    /// <summary> /// 提取字符串中的数字 /// </summary> /// <param name="str"></pa ...

  4. C#多线程案例基础

    C#多线程案例基础(转) 在学习多线程之前,我们先来看几个概念: 1,什么是进程?    当一个程序开始运行时,它就是一个进程,进程包括运行中的程序和程序所使用到的内存和系统资源,当然一个程序也可能开 ...

  5. 如何利用jq来实现复选框的全选,反选!

    $("document").ready(function(){ $("#btn1").click(function(){ $("[name='chec ...

  6. vs2010 编译curl-7.42.1

    curl是一个sftp ssl 等功能工具. dos 进入到curl-7.42.1\lib下来:逐步执行以下操作 call "C:/Program Files/Microsoft Visua ...

  7. thinkphp验证码点击更换js实现

    <img src="__CONTROLLER__/verify" alt="" onclick=this.src="__CONTROLLER__ ...

  8. JavaScript高级 面向对象的程序设计 (二)《JavaScript高级程序设计(第三版)》

    二.继承 OO是面向对象语言最为有魅力的概念.一般的OO语言都实现了两种继承,接口继承和实现继承.接口继承只继承方法签名,而实际继承继承了实际的方法. 而在JS中,函数没有签名,所以无法实现接口继承. ...

  9. 简单实现兼容各大浏览器的js复制内容到剪切板

    因为网站文章需要提供几个按钮,单击后实现复制文章内容到剪贴板. 在网上搜索了很多内容,发现都比较乱这里自己整理下,分享给大家 效果图如下: 之前使用的是window.clipboardData.set ...

  10. PL/SQL Developer基本用法

    一.新建存储过程