62

我开始使用存储库模式进行数据访问,使用实体框架LINQ作为非测试存储库实现的基础。当调用返回 N 条记录而不是 List<T> 时,我看到的大多数示例都返回 AsQueryable()。这样做有什么好处?

4

5 回答 5

102

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

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

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

于 2009-07-09T22:41:48.977 回答
25

返回IQueryable<T>的好处是,在您真正开始枚举结果之前执行会延迟,并且您可以将查询与其他查询组合在一起,并且仍然可以在服务器端执行。

问题是您无法在此方法中控制数据库上下文的生命周期 - 您需要一个开放的上下文,并且必须确保它保持打开状态,直到查询被执行。然后你必须确保上下文将被释放。List<T>如果您以、或类似的形式返回结果T[],您将失去组合查询的延迟执行和服务器端执行,但您可以控制数据库上下文的生命周期。

当然,什么最适合,取决于实际要求。这是另一个没有单一真理的问题。

于 2009-07-09T23:17:17.923 回答
11

AsQueryable是一种扩展方法,IEnumerable<T>它可以做两件事:

  • 如果IEnumerable<T>工具IQueryable<T>只是强制转换,什么也不做。
  • 否则会创建一个“假” IEnumerable<T>EnumerableQuery<T>)来实现编译 lambdas 并调用 Enumerable 扩展方法的每个方法。

因此,在大多数情况下,使用 AsQueryable 是没有用的,除非你被迫将 IQueryable 传递给一个方法,而你有一个 IEnumerable,否则这是一个 hack。

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

于 2010-11-04T12:08:31.960 回答
4

返回IQueryable<T>将推迟查询的执行,直到它的结果被实际使用。在此之前,您还可以对 ; 执行额外的数据库查询操作IQueryable<T>。在List你被限制在通常效率较低的内存操作中。

于 2009-07-09T22:46:56.203 回答
-1
  • IQueryable:这是一种延迟执行 - 延迟加载,因此您的查询被评估并命中数据库。如果我们添加任何附加子句,它将使用带有过滤器的所需查询命中 Db。
  • IEnumerable:是急切加载,因此记录将首先加载到内存中操作,然后执行操作。

因此,取决于用例,例如在对大量记录进行分页时,我们应该使用IQueryable<T>,如果操作时间短且不会创建大量内存存储使用IEnumerable

于 2020-06-15T09:45:10.143 回答