任逍遥

 找回密码
 立即注册
查看: 30873|回复: 99

浅谈EF中LINQ查询原理

    [复制链接]
  • TA的每日心情

    2020-9-5 20:20
  • 签到天数: 487 天

    连续签到: 1 天

    [LV.9]妙领天机

    530

    主题

    3428

    帖子

    4569

    积分

    如雷贯耳

    Rank: 8Rank: 8

    积分
    4569
    发表于 2018-7-23 21:36:29 | 显示全部楼层 |阅读模式

    马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。

    您需要 登录 才可以下载或查看,没有帐号?立即注册

    x

      在接触Linq之前,一直听说Linq被微软抛弃。后来才发现被抛弃的是Linq to SQL这种专用于操作Sql Server的轻型ORM,微软宣布停止更新Linq to Sql,把开发的重点从 Linq to SQL 转移到了 Linq to Entities。
      在EF中使用Linq查询数据的基本形式是这样的:
      var result = from t in Table where t.id > 10 select t;
      这个形式在Linq to 各种都是通用的,下面讲一下它的原理。
      很多人都以为,上面的语句执行过后就完成了查询操作,把查询的结果载入了result中,然而事实是上面的语句只完成了一个result对象的创建和初始化。事实上真正的查询是在foreach语句开始时发生的,查询到的数据载入,然后再遍历取数据。你可以尝试在Sql Server的profile工具中监控一下,上面的语句执行完成,数据库并没有监控到任何信息,当你尝试在"result“中拿数据的时候,profile工具监测到了数据库访问,这也就是延时加载,如果你想关闭延时加载可以在EF模型的属性中设置。
      这里的result的类型其实是DbQuery,它有实现一个接口IQueryable<>,IQueryable<>是Linq命名空间下的一个特有的集合,它的类型参数是实体类或其父类,或者不用泛型,默认的是Object,这涉及到协变。由于采用了延时加载,所以说这是一种离线集合。也就是说你尝试在"result"中取一次数据,它就会去数据库查询一次,所以如果需要持续使用某些数据,应该是手动创建对象,存入本地内存中。
      那么Linq查询的原理和IQueryable<>有什么关系呢?其实在IQueryable<>中仅有三个属性:
      Type ElementType
      Expression Expression
      IQueryProvider Provider
      我们在写Linq表达式并完成IQueryable<>对象创建的时候,它的初始化过程是这样的:声明元素类型,这一点从属性名字就可以看出来,然后建立Expression对象,这里就是把你写的Linq表达式进行解析,拆分,解析成一个表达式树,也就是对Lambda表达式的解析过程,Expression对象以二叉树结构存储解析结果。最后根据LINQ表达式类型给IQueryableProvider provider属性赋值。在你需要读取数据的时候Provider属性就去解析Expression表达式树执行查询返回。所以这就做到了不管你是Linq to Sql还是Linq to Entities,都能使用。
      其实EF跨数据库的核心也在这里,目前多个数据库厂商开始逐渐支持EF,他们只需要做一个工作,那就是写对应数据库的Provider驱动即可,你可以在自己的项目中引用不同数据库的Provider,然后更改连接字符串的providerName属性就完成了跨数据库操作。
      有时候我们可以直接把Linq的查询结果载入本地集合,也就是List,Array这样,存入内存中。Linq表达式可以这样写:
      var result = from t in Table.ToList() where t.id > 10 select t;
      这时候查询就变成了Linq to Object,上面不同,在这条语句执行完成过后,数据就已经从数据库中查询,载入内存,变成了Object。所以这里的所有操作都是在内存中进行,如果不适用ToList()函数,最后执行的SQL语句中加入了Linq表达式中的where条件,而这种方法则是将数据全部载入内存,在内存中使用where的筛选条件过滤。
    楼主热帖
  • TA的每日心情

    2019-8-30 04:55
  • 签到天数: 462 天

    连续签到: 1 天

    [LV.9]妙领天机

    1

    主题

    2924

    帖子

    2924

    积分

    声名显赫

    Rank: 7Rank: 7Rank: 7

    积分
    2924
    发表于 2018-7-23 21:40:22 | 显示全部楼层
    是爷们的娘们的都帮顶!大力支持
    回复

    使用道具 举报

  • TA的每日心情
    开心
    2019-8-30 12:19
  • 签到天数: 460 天

    连续签到: 1 天

    [LV.9]妙领天机

    1

    主题

    2891

    帖子

    2891

    积分

    声名显赫

    Rank: 7Rank: 7Rank: 7

    积分
    2891
    发表于 2018-7-25 09:50:19 | 显示全部楼层
    看起来好像不错的样子
    回复

    使用道具 举报

  • TA的每日心情
    开心
    2019-8-30 12:49
  • 签到天数: 468 天

    连续签到: 6 天

    [LV.9]妙领天机

    4

    主题

    2912

    帖子

    2913

    积分

    声名显赫

    Rank: 7Rank: 7Rank: 7

    积分
    2913
    发表于 2018-7-26 02:55:04 | 显示全部楼层
    支持,赞一个
    回复

    使用道具 举报

  • TA的每日心情
    开心
    2019-8-30 15:35
  • 签到天数: 461 天

    连续签到: 1 天

    [LV.9]妙领天机

    2

    主题

    2983

    帖子

    2984

    积分

    声名显赫

    Rank: 7Rank: 7Rank: 7

    积分
    2984
    发表于 2018-7-26 08:36:58 | 显示全部楼层
    回个帖子,下班咯~
    回复

    使用道具 举报

  • TA的每日心情

    2019-8-29 03:36
  • 签到天数: 463 天

    连续签到: 4 天

    [LV.9]妙领天机

    13

    主题

    2921

    帖子

    2934

    积分

    声名显赫

    Rank: 7Rank: 7Rank: 7

    积分
    2934
    发表于 2018-7-28 04:30:29 | 显示全部楼层
    报告!别开枪,我就是路过来看看的。。。
    回复

    使用道具 举报

  • TA的每日心情

    2019-8-30 13:09
  • 签到天数: 473 天

    连续签到: 3 天

    [LV.9]妙领天机

    2

    主题

    2995

    帖子

    2997

    积分

    声名显赫

    Rank: 7Rank: 7Rank: 7

    积分
    2997
    发表于 2018-7-30 14:40:59 | 显示全部楼层
    好,很好,非常好!
    回复

    使用道具 举报

  • TA的每日心情
    难过
    2019-8-30 07:42
  • 签到天数: 476 天

    连续签到: 6 天

    [LV.9]妙领天机

    3

    主题

    2954

    帖子

    2957

    积分

    声名显赫

    Rank: 7Rank: 7Rank: 7

    积分
    2957
    发表于 2018-8-2 02:46:03 | 显示全部楼层
    楼主呀,,,您太有才了。。。
    回复

    使用道具 举报

  • TA的每日心情
    难过
    2019-8-28 11:57
  • 签到天数: 464 天

    连续签到: 8 天

    [LV.9]妙领天机

    12

    主题

    2935

    帖子

    2947

    积分

    声名显赫

    Rank: 7Rank: 7Rank: 7

    积分
    2947
    发表于 2018-8-6 06:20:39 | 显示全部楼层
    报告!别开枪,我就是路过来看看的。。。
    回复

    使用道具 举报

  • TA的每日心情

    2019-8-30 06:12
  • 签到天数: 453 天

    连续签到: 2 天

    [LV.9]妙领天机

    4

    主题

    2906

    帖子

    2910

    积分

    声名显赫

    Rank: 7Rank: 7Rank: 7

    积分
    2910
    发表于 2018-8-9 23:17:39 | 显示全部楼层
    看帖要回,回帖才健康,在踩踩,楼主辛苦了!
    回复

    使用道具 举报

    您需要登录后才可以回帖 登录 | 立即注册

    本版积分规则

    QQ|Archiver|手机版|小黑屋|任逍遥

    GMT+8, 2024-5-1 01:42 , Processed in 0.083653 second(s), 49 queries .

    Powered by 任逍遥 X3.4

    Copyright © 2001-2023, Rxiaoyao Cloud.

    快速回复 返回顶部 返回列表