我正在使用存储库模式进行数据访问,并使用 Entity Framework 和 LINQ 作为非测试存储库实现的基础。当调用返回 N 条记录而不是 List
AsQueryable 只是创建一个查询,获取列表所需的指令。您可以稍后对查询进行进一步更改,例如添加新的Where子句,这些子句会一直发送到数据库级别。
AsList 返回一个包含内存中所有项目的实际列表。如果向其中添加新的Where 线索,您将无法获得数据库提供的快速过滤功能。相反,您获取列表中的所有信息,然后过滤掉应用程序中不需要的信息。
所以基本上可以归结为等到最后一刻才做出承诺。
返回
IQueryable<T>
的优点是,执行会延迟,直到您真正开始枚举结果,并且您可以与其他查询组合查询并仍然获得服务器端执行。
问题是您无法在此方法中控制数据库上下文的生命周期 - 您需要一个打开的上下文,并且必须确保它在查询执行之前保持打开状态。然后你必须确保上下文将被处理。如果您以
List<T>
、T[]
或类似的形式返回结果,您将失去组合查询的延迟执行和服务器端执行,但您赢得了对数据库上下文生命周期的控制。
当然,哪种最适合,取决于实际需求。这是另一个没有任何事实真相的问题。
AsQueryable
是 IEnumerable<T>
的扩展方法,可以做两件事:
IEnumerable<T>
实现 IQueryable<T>
只是强制转换,不执行任何操作。 IEnumerable<T>
(EnumerableQuery<T>
),它实现编译 lambda 并调用 Enumerable 扩展方法的每个方法。 所以在大多数情况下使用 AsQueryable 是没有用的,除非你被迫将 IQueryable 传递给方法并且你有一个 IEnumerable 来代替,这是一个 hack。
注意:AsQueryable 是一种 hack,IQueryable 当然不是!
返回
IQueryable<T>
将推迟查询的执行,直到实际使用其结果。在此之前,您还可以对IQueryable<T>
执行额外的数据库查询操作;在 List
上,您只能进行通常效率较低的内存操作。
IQueryable
:IEnumerable
:是急切加载,因此记录将首先加载内存操作,然后执行操作。因此,根据使用情况,例如在对大量记录进行分页时,我们应该使用
IQueryable<T>
,前提是 DBcontext 在执行之前处于打开状态,如果操作较短并且不会创建巨大的内存存储,则可以使用 IEnumerable
。