当前位置: 移动技术网 > IT编程>开发语言>.net > IQueryable和IEnumerable以及AsEnumerable()和ToList()的区别

IQueryable和IEnumerable以及AsEnumerable()和ToList()的区别

2018年11月11日  | 移动技术网IT编程  | 我要评论

nba录像回放,迪鲁卡,林乐怡

注意:本文背景为 linq to sql 。文中ie指代ienumerableiq指代iqueryable

iqueryable 和 ienumerable 的区别

  • iqueryable
    延时执行;扩展方法接受的是expression(必须要能转成sql,否则报错)

  • ienumerable
    延时执行;扩展方法接受的是func(c#语法)

asenumerable() 和 tolist() 的区别

  • tolist()
    立即执行,加载数据到内存中。

  • asenumerable()
    延迟执行,真正使用时才加载数据。
    对iqueryable对象使用asenumerable()后,仍然是延迟执行,不过此时对象本质已经变了。
    前面已经说了ienumerable的扩展方法接受的是func(c#语法),当ie对象(iq转变)真正使用时,会有2个步骤:
    1.它会把iq对象(转变之前的)的扩展方法翻译成sql语句,查询出数据加载到内存中,变为ie对象;
    2.此时再把ie对象(转变之后的)的扩展方法,使用c#求解,得到最终结果。
    例如:iq对象的skip、take方法,会被翻译成sql,在数据库里执行取出最终结果。
    而ie对象的skip、take方法,则会取出全部数据到内存中,在内存中执行skip、take,会耗费大量资源。

误区

  • 误区1:对 iq对象 和 ie对象 使用foreach时,对于循环的每项都要查询数据库。

    错误!
    foreach针对的是数据集整体对象(枚举器?)。当使用foreach时,不管是iq对象还是ie对象,它们都是查询数据库一次,然后开始循环,直至循环结束。不过,当后续再次使用iq对象或ie对象的具体数据时,它们仍然会再次查询数据库。

结论

假设我们把最终数据之前的数据称为中间数据,那么:

  1. 中间数据只是作为条件筛选,需要的只是层层筛选之后的最终数据时,应该继续使用iqueryable,防止加载不必要的数据到内存中。
  2. 存在中间数据,且中间数据被重复使用时,应该使用iqueryable.tolist()立即加载到内存里使用(都被重复使用了,应该叫做最终数据了吧..);
  3. 如果中间结果无用,且想对iqueryable对象使用func(c#语法)的扩展方法,应该使用iqueryable.asenumerable()转成ienumerable对象,进行后续操作。

参考

  1. linq查询中的ienumerable<t>和iqueryable<t>
  2. linq使用细节之.asenumerable()和.tolist()的区别
  3. 建议29:区别linq查询中的ienumerable<t>和iqueryable<t> - 陆敏技《编写高质量代码改善c#程序的157个建议》

如对本文有疑问,请在下面进行留言讨论,广大热心网友会与你互动!! 点击进行留言回复

相关文章:

验证码:
移动技术网