为什么使用AsQueryable()而不是List()?

问题描述 投票:0回答:5

我正在使用存储库模式进行数据访问,并使用 Entity FrameworkLINQ 作为非测试存储库实现的基础。当调用返回 N 条记录而不是 List 时,我看到的大多数示例都会返回 AsQueryable()。这样做有什么好处?

c# linq repository iqueryable
5个回答
106
投票

AsQueryable 只是创建一个查询,获取列表所需的指令。您可以稍后对查询进行进一步更改,例如添加新的Where子句,这些子句会一直发送到数据库级别。

AsList 返回一个包含内存中所有项目的实际列表。如果向其中添加新的Where 线索,您将无法获得数据库提供的快速过滤功能。相反,您获取列表中的所有信息,然后过滤掉应用程序中不需要的信息。

所以基本上可以归结为等到最后一刻才做出承诺。


26
投票

返回

IQueryable<T>
的优点是,执行会延迟,直到您真正开始枚举结果,并且您可以与其他查询组合查询并仍然获得服务器端执行。

问题是您无法在此方法中控制数据库上下文的生命周期 - 您需要一个打开的上下文,并且必须确保它在查询执行之前保持打开状态。然后你必须确保上下文将被处理。如果您以

List<T>
T[]
或类似的形式返回结果,您将失去组合查询的延迟执行和服务器端执行,但您赢得了对数据库上下文生命周期的控制。

当然,哪种最适合,取决于实际需求。这是另一个没有任何事实真相的问题。


13
投票

AsQueryable
IEnumerable<T>
的扩展方法,可以做两件事:

  • 如果
    IEnumerable<T>
    实现
    IQueryable<T>
    只是强制转换,不执行任何操作。
  • 否则会创建一个“假”
    IEnumerable<T>
    (
    EnumerableQuery<T>
    ),它实现编译 lambda 并调用 Enumerable 扩展方法的每个方法。

所以在大多数情况下使用 AsQueryable 是没有用的,除非你被迫将 IQueryable 传递给方法并且你有一个 IEnumerable 来代替,这是一个 hack。

注意:AsQueryable 是一种 hack,IQueryable 当然不是!


4
投票

返回

IQueryable<T>
将推迟查询的执行,直到实际使用其结果。在此之前,您还可以对
IQueryable<T>
执行额外的数据库查询操作;在
List
上,您只能进行通常效率较低的内存操作。


-1
投票
  • IQueryable
  • 这是一种延迟执行 - 延迟加载,因此您的查询是 评估并命中数据库。如果我们添加任何附加条款 将使用所需的查询和过滤器访问数据库并返回 只需要结果。
  • 将被评估/差异,直到最终执行/调用。
  • IEnumerable
    :是急切加载,因此记录将首先加载内存操作,然后执行操作。
  • 因此,如果对此集合执行任何查询,那么首先是所有数据 将被加载到内存中,然后过滤以返回所需的。

因此,根据使用情况,例如在对大量记录进行分页时,我们应该使用

IQueryable<T>
,前提是 DBcontext 在执行之前处于打开状态,如果操作较短并且不会创建巨大的内存存储,则可以使用
IEnumerable

© www.soinside.com 2019 - 2024. All rights reserved.