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

ecr0jaav  于 12个月前  发布在  其他
关注(0)|答案(5)|浏览(134)

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

f8rj6qna

f8rj6qna1#

AsQueryable只是创建一个查询,即获取列表所需的指令。您可以稍后对查询进行进一步更改,例如添加新的Where子句,这些子句将一直发送到数据库级别。
AsList返回一个实际的列表,其中包含内存中的所有项。如果向其中添加一个新的Where类,则无法获得数据库提供的快速过滤功能。相反,您将获得列表中的所有信息,然后过滤掉应用程序中不需要的信息。
所以基本上它归结为等待,直到最后一个可能的时刻之前,承诺自己。

dy2hfwbg

dy2hfwbg2#

返回IQueryable<T>有一个好处,那就是直到你真正开始枚举结果之前,执行是不同的,你可以将查询与其他查询组合在一起,仍然可以在服务器端执行。
问题是你不能在这个方法中控制数据库上下文的生存期--你需要一个开放的上下文,并且必须确保它在查询执行之前保持开放状态。然后你必须确保上下文将被释放。如果你返回的结果是List<T>T[]或类似的东西,你就失去了组合查询的延迟执行和服务器端执行,但是您赢得了对数据库上下文生存期的控制。
当然,什么最适合,取决于实际需要。这是另一个没有单一真理的问题。

wz8daaqr

wz8daaqr3#

AsQueryableIEnumerable<T>的一个扩展方法,可以做两件事:

  • 如果IEnumerable<T>实现了IQueryable<T>,则只进行强制转换,什么也不做。
  • 否则,创建一个“假”IEnumerable<T>EnumerableQuery<T>),它实现了编译EQUIPDAS和调用EQUIPDAS扩展方法的每个方法。

所以在大多数情况下使用AsQueryable是无用的,除非你被迫传递一个IQueryable给一个方法,而你有一个IEQuery,这是一个黑客。
注意:AsQueryable是一个黑客,IQueryable当然不是!

qmelpv7a

qmelpv7a4#

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

nnsrf1az

nnsrf1az5#

  • IQueryable
  • 这是一种延迟执行-延迟加载,因此您的查询被评估并命中数据库。如果我们添加任何额外的子句,它将使用所需的查询沿着过滤器来命中Db,并仅返回所需的结果。
  • 在最终执行/调用之前将进行评估/区分。
  • IEnumerable:是即时加载,因此记录将首先加载内存操作,然后执行操作。
  • 因此,如果对该集合执行任何查询,则首先将所有数据加载到内存中,然后过滤以返回required。

因此,根据使用情况,例如在大量记录上分页时,我们应该使用IQueryable<T>,前提是DBcontext在执行之前是打开的,如果短操作并且不创建巨大的内存存储,则可以使用IEnumerable

相关问题