为什么使用 AsQueryable() 而不是 List()?
我正在使用存储库模式通过 Entity Framework 和 LINQ 作为非测试存储库实现的基础。 当调用返回 N 条记录而不是 List
I'm getting into using the Repository Pattern for data access with the Entity Framework and LINQ as the underpinning of implementation of the non-Test Repository. Most samples I see return AsQueryable() when the call returns N records instead of List<T>. What is the advantage of doing this?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(5)
AsQueryable 只是创建一个查询,获取列表所需的指令。 您可以稍后对查询进行进一步更改,例如添加一直发送到数据库级别的新Where 子句。
AsList 返回一个包含内存中所有项目的实际列表。 如果向其中添加新的Where 线索,您将无法获得数据库提供的快速过滤功能。 相反,您获取列表中的所有信息,然后过滤掉应用程序中不需要的信息。
所以基本上,归根结底就是要等到最后一刻才做出承诺。
AsQueryable just creates a query, the instructions needed to get a list. You can make futher changes to the query later such as adding new Where clauses that get sent all the way down to the database level.
AsList returns an actual list with all the items in memory. If you add a new Where cluse to it, you don't get the fast filtering the database provides. Instead you get all the information in the list and then filter out what you don't need in the application.
So basically it comes down to waiting until the last possible momment before committing yourself.
返回
IQueryable
的优点是,执行会延迟,直到您真正开始枚举结果,并且您可以将查询与其他查询组合在一起,并且仍然获得服务器端执行。问题是您无法在此方法中控制数据库上下文的生命周期 - 您需要一个打开的上下文,并且必须确保它在执行查询之前保持打开状态。 然后你必须确保上下文将被处理。 如果您以
List
、T[]
或类似形式返回结果,您将失去组合查询的延迟执行和服务器端执行,但您赢得了控制权在数据库上下文的生命周期内。当然,什么最适合,取决于实际需求。 这是另一个没有任何事实真相的问题。
Returning
IQueryable<T>
has the advantage, that the execution is defferer until you really start enumerating the result and you can compose the query with other queries and still get server side execution.The problem is that you cannot control the lifetime of the database context in this method - you need an open context and must ensure that it stays open until the query gets executed. And then you must ensure that the context will be disposed. If you return the result as a
List<T>
,T[]
, or something similar, you loose deffered execution and server side execution of composed queries, but you win control over the lifetime of the database context.What fits best, of course, depends on the actual requirements. It's another question without a single truth.
AsQueryable
是IEnumerable
的扩展方法,它可以做两件事:IEnumerable
实现IQueryable;
只是强制转换,什么也不做。IEnumerable
(EnumerableQuery
),它实现编译 lambda 并调用 Enumerable 扩展方法的每个方法。因此,在大多数情况下,使用 AsQueryable 是没有用的,除非您被迫将 IQueryable 传递给方法并且您有一个 IEnumerable,否则这是一种 hack。
注意:AsQueryable 是一种 hack,IQueryable 当然不是!
AsQueryable
is an extension method forIEnumerable<T>
that could do two things:IEnumerable<T>
implementsIQueryable<T>
justs casts, doing nothing.IEnumerable<T>
(EnumerableQuery<T>
) that implements every method compiling the lambdas and calling to Enumerable extension methods.So in most of the cases using AsQueryable is useless, unless u are forced to pass a IQueryable to a method and u have a IEnumerable instead, it's a hack.
NOTE: AsQueryable is a hack, IQueryable of course is not!
返回
IQueryable
将推迟查询的执行,直到实际使用其结果。 在此之前,您还可以对IQueryable
执行其他数据库查询操作; 在List
上,您只能进行通常效率较低的内存操作。Returning
IQueryable<T>
will defer execution of the query until its results are actually used. Until then, you can also perform additional database query operations on theIQueryable<T>
; on aList
you're restricted to generally less-efficient in-memory operations.IQueryable
:评估并命中数据库。 如果我们添加任何附加条款
将使用所需的查询和过滤器访问数据库并返回
仅需要结果。
IEnumerable
:是急切加载,因此记录将首先加载内存操作,然后执行操作。将被加载到内存中,然后过滤以返回所需的。
因此,根据使用情况,例如在对大量记录进行分页时,我们应该使用
IQueryable
,前提是 DBcontext 在执行之前保持打开状态,如果操作较短且不会创建巨大的内存存储,则可以使用IEnumerable
。IQueryable
:evaluated and hit to database. If we add any additional clause it
will hit the Db with the required query along with filters and return
only required result.
IEnumerable
: Is eager loading thus records will be loaded first in-memory operation and then the operation will be performed.will be loaded in memory and then filter to return required.
So depending on use case like while paging on a huge number of records we should use
IQueryable<T>
provided that DBcontext is open till the execution, if short operation and doesn't create huge memory storage you can go withIEnumerable
.