我开始使用存储库模式进行数据访问,Entity Framework和LINQ作为非测试存储库实现的基础。我看到的大多数样本在调用返回N个记录而不是List< T>时返回AsQueryable()。这样做有什么好处?
答案 0 :(得分:88)
AsQueryable只创建一个查询,获取列表所需的指令。您可以稍后对查询进行进一步更改,例如添加新的Where子句,这些子句一直发送到数据库级别。
AsList返回包含内存中所有项目的实际列表。如果您添加一个新的Where cluse,则不会获得数据库提供的快速过滤。而是获取列表中的所有信息,然后过滤掉应用程序中不需要的内容。
所以基本上归结为等到最后一次可能的妈妈才能做出承诺。
答案 1 :(得分:23)
返回IQueryable<T>
有一个好处,即执行是defferer,直到你真正开始枚举结果,你可以用其他查询编写查询并仍然得到服务器端执行。
问题是您无法在此方法中控制数据库上下文的生命周期 - 您需要一个开放的上下文,并且必须确保它在查询执行之前保持打开状态。然后你必须确保处理上下文。如果将结果作为List<T>
,T[]
或类似的结果返回,则会丢失组合查询的违反执行和服务器端执行,但您可以控制数据库上下文的生命周期。
最适合的当然,取决于实际要求。这是另一个没有一个真理的问题。
答案 2 :(得分:11)
AsQueryable
是IEnumerable<T>
的扩展方法,可以做两件事:
IEnumerable<T>
实施IQueryable<T>
justs施放,则什么都不做。 IEnumerable<T>
(EnumerableQuery<T>
),它实现编译lambda并调用Enumerable扩展方法的每个方法。 所以在大多数情况下使用AsQueryable是没用的,除非你被迫将IQueryable传递给一个方法而你有一个IEnumerable,这是一个黑客攻击。
注意:AsQueryable是一个hack,IQueryable当然不是!
答案 3 :(得分:4)
返回IQueryable<T>
将推迟执行查询,直到实际使用结果为止。在此之前,您还可以在IQueryable<T>
上执行其他数据库查询操作;在List
上,你被限制在通常效率低下的内存操作中。
答案 4 :(得分:-1)
IQueryable
:这是一种延迟执行-延迟加载,因此可以评估您的查询并将其命中数据库。如果我们添加任何其他子句,它将通过带有过滤器的必需查询到达Db。IEnumerable
:渴望加载,因此将先在内存中加载记录,然后再执行该操作。因此,根据使用情况,例如在对大量记录进行分页时,我们应该使用IQueryable<T>
,如果操作简短且不会创建大量内存,请使用IEnumerable
。