本人初学linq,有个地方不明白,.ToList()和AsEnumerable(),按照文档上来说 .ToList是直接执 行,AsEnumerable是延迟执行,其实没任何意义,只有要使用结果集的时候才会查询数据库,如果不需要使用结果集,并且要延迟的i情况下可以使用 AsEnumerable,我有个疑问,一般查询不是都要用到结果集么,那么AsEnumerable的使用场景是不是很少呢,能不能举例几个 AsEnumerable的使用场景,可以让我更加的形象了解AsEnumerable具体适合哪些地方用
你应该搞错了。
AsQueryable 是延时的
AsEnumerable 是及时的
https://blog.youkuaiyun.com/hanjun0612/article/details/50070081
另外,延迟加载的场景。
假设有一个User表,它有个关联表 Address。
你要显示User信息,但Address是不要显示。
所以他可以是延时的。
只有用到了,才会去加载。没用到,就不加载。
你可以自己通过ef创建数据库映射,然后测试一下。
这是我当初的测试片段
对应的产生如下2个sql语句。
AsEnumerable比较明显的是,全表缓存。之后才在内存里筛选数据
MSDN上也说的比较清晰。
当你使用 where时,传入Expression<Func>表达式树,就如我上面的IQueryable<>一样,组装sql语句。
当你不需要,则转为AsEnumerable。他不是拼接表达式树的,而是直接调用本地方法,对内存里的数据进行筛选。
我想,你可能讨论的延迟,和我理解的稍有不同。
ToList,First(),FirstOrdefault,take。。。。,是把数据加载到本地。
你在没有执行时如上方法时,的确不会装载到内存里。
给你一个必须用IEnumerator的场景,就是微软的类库中,有大量的使用,或者说,你追求写自己写“高性能”类库时,也必须用IEnumerator,而不是List。
为什么?因为使用迭代器,可以最高效的遍历列表,也就是用多少取多少,而不是全部装载到一个新的List里来用(假设你要取一个结果集最多可能有100万个项,你是全装载到List,还是随用随取,更省资源)。
这就有点“八股”了。
ToList 是返回 List<>类型,这个类型有着复杂的一大堆内容,非常非常复杂,细节许多。要实现它就必须将查询发送到数据库去,将 结果取过来,然后将结果缓存到 List<> 结构中。如果有 n个地方用到了 ToList 的结果对象,那么其实也仅仅查询数据库一次。
AsEnumerable 是返回可枚举的接口类型,是非常简单非常轻的接口,可能只有 ToList 的百分之一而已,没有额外的细节要求。要实现这个 接口就可以仅仅保存编译好查询规划,然后当读取数据时一遍遍地“重复地”将查询发送到数据库去,一遍遍地重复取结果过来。这样的好处当然是推迟到真正读取 数据的时候才发送查询语句,如果不走到延迟的最后一步而提前结束了,那么就无需真正去数据库查询了。坏处当然就是如果有n个地方都用到 了 AsEnumerable 的结果对象,那么其实是反复查询了数据库 n 次。
如果仅仅查询一次,那么使用 AsEnumerable 则可以得到一个“轻量级”的结果,那么程序的任意流程如果没有走到实际读取查询结果的地步时,就等于是没有花费普通c#代码几万倍的性能代价去读取和序列化数据库了。
而假设你认为代码根本不可能走不到实际读取查询结果的地步,那么你自然可以使用 ToList 也可以使用 AsEnumerable ,没有什么差别。
我说“八股”的实际意思是,其实类似 AsEnumerable 这类所要表达是一类设计模式,而不是具体实现。所以理解二者的差别等多地是要从一种文档的规范制定者的角度去理解,切不可从最低级的工程师的角度去理解。
可以肯定地说,有不少不同框架 provider 具体实现某种类型业务对象的 AsEnumerable 封装功能时,可能直接返回 ToList 结 果,或者是直接把数据装载在内存缓存里,然后返回。但是软件的“是非”是以测试为准的,只要是人家对于 AsEnumerable 的实现(暂时地)让你 测试通过了,给了你要的数据结果,那么可能你也就暂时不用去纠结 AsEnumerable 和 ToList 的区别了。你所要坚持的只能是这两个东西 在“期望上的”区别,而不能八股地认为这种区别是死的东西预先写好的。真正http://www.9ibee.com/这两个区别是接口设计者——.net框架设计总工程师以及一些.net框架书籍 传播者——给出来的正确理念,仅仅是理念,希望大家都以此为合同(接口)来实现各类 AsEnumerable 实现,而不是死要求。
如果provider支持服务器游标的话,那么asenumerable占用内存更少
本文深入探讨了Linq中ToList与AsEnumerable方法的使用场景与性能差异。ToList会立即执行查询并将结果缓存到List中,适用于需要多次访问相同数据集的情况。AsEnumerable则是延迟执行,仅在数据被实际读取时执行查询,适用于不确定是否需要结果集或避免多次查询数据库的场景。
1199

被折叠的 条评论
为什么被折叠?



