当我在寻找提高性能的方法时,我遇到了这篇帖子。目前,在我的应用程序中,我们到处都返回 IList
。将所有这些返回更改为 AsQueryable()
是个好主意吗?
这是我发现的 -
-
AsQueryable()
- 上下文需要是
打开并且您无法控制
数据库上下文的生命周期
它需要妥善处理。还
它是延迟执行('更快
与列表相比)
-
IList<>
- 这应该是首选
优于 List<>
,因为它提供了准系统
和轻量级的实现。
另外什么时候应该优先选择一个而不是另一个?我了解基础知识,但很抱歉我仍然不清楚我们何时以及如何在应用程序中正确使用它们。很高兴知道这一点,因为下次我会在退回任何东西之前记住这一点。非常感谢。
I came across this post while I was looking for things to improve performance. Currently, in my application we are returning IList<>
all over the place. Is it a good idea to change all of these returns to AsQueryable()
?
Here is what I found -
AsQueryable()
- Context needs to be
open and you cannot control the
lifetime of the database context
it need to be disposed properly. Also
it is deferred execution('faster
filtering' as compared to Lists)
IList<>
- This should be preferred
over List<>
as it provides a barebone
and lightweight implementation.
Also when should be one preferred over another ? I know the basics but I am sorry I am still not clear when and how should we use them correctly in an application. It would be great to know this as the next time I would try to keep it in mind before returning anything..Thanks a lot.
发布评论
评论(3)
基本上,您应该尝试引用您需要的最广泛的类型。例如,如果某个变量被声明为
List<...>
,则可以对可以分配给它的值的类型设置约束。您可能只需要顺序访问,因此将变量声明为IEnumerable<...>
就足够了。这将允许您将其他类型的值以及 LINQ 操作的结果分配给变量。如果您发现变量需要通过索引访问,您可以再次将其声明为
IList<...>
而不仅仅是List<...>
,从而允许实现IList<...>
的其他类型将分配给它。对于函数返回类型,这取决于您。如果您认为函数准确返回
List<...>
很重要,则可以将其声明为准确返回List<...>
。如果唯一重要的是通过索引访问结果,也许您不需要限制自己完全返回List<...>
,您可以将返回类型声明为IList< ;...>
(但在此实现中实际上返回一个List<...>
的实例,并且可能是支持IList<... 的另一种类型>
稍后)。同样,如果您发现函数的返回值唯一重要的是它可以枚举(并且不需要通过索引访问),则应该将函数返回类型更改为IEnumerable<... >
,给自己更多的自由。现在,关于
AsQueriable
,这又取决于您的逻辑。如果您认为可能的延迟评估在您的情况下是一件好事,因为它可能有助于避免不需要的计算,或者您打算将其用作其他查询的一部分,那么您可以使用它。如果您认为结果必须“具体化”,即在此时计算,您最好返回一个List<...>
。如果稍后的计算可能会产生不同的列表,您尤其需要具体化您的结果!对于数据库,一个好的经验法则是使用
AsQueriable
来获取短期中间结果,而使用List
来获取将在较长时间内使用的“最终”结果。当然,如果存在非具体化查询,则无法关闭数据库(因为在实际评估数据库时,数据库应该仍处于打开状态)。Basically, you should try to reference the widest type you need. For example, if some variable is declared as
List<...>
, you put a constraint for the type of the values that can be assigned to it. It may happen that you need only sequential access, so it would be enough to declare the variable asIEnumerable<...>
instead. That will allow you to assign the values of other types to the variable, as well as the results of LINQ operations.If you see that your variable needs access by index, you can again declare it as
IList<...>
and not justList<...>
, allowing other types implementingIList<...>
be assigned to it.For the function return types, it depends upon you. If you think it's important that the function returns exactly
List<...>
, you declare it to return exactlyList<...>
. If the only important thing is access to the result by index, perhaps you don't need to constrain yourself to return exactlyList<...>
, you may declare return type asIList<...>
(but return actually an instance ofList<...>
in this implementation, and possibly of some another type supportingIList<...>
later). Again, if you see that the only important thing about the return value of your function is that it can be enumerated (and the access by index is not needed), you should change the function return type toIEnumerable<...>
, giving yourself more freedom.Now, about
AsQueriable
, again it depends on your logic. If you think that possible delayed evaluation is a good thing in your case, as it may aid to avoid the unneeded calculations, or you intend to use it as a part of some another query, you use it. If you think that the results have to be "materialized", i.e., calculated at this very moment, you would better return aList<...>
. You would especially need to materialize your result if the calculation later may result in a different list!With the database a good rule of thumb is to use
AsQueriable
for the short-term intermediate results, butList
for the "final" results which will be used within some longer time. Of course having a non-materialized query hanging around makes closing the database impossible (since at the moment of actual evaluation of the the database should be still open).如果您不打算通过 sql server 进行任何进一步的查询,那么您应该返回 IList,因为它会生成内存中的数据
if you do not intend to do any further queries over sql server then you should return IList because it produces in-memory data
如果您担心性能,您还应该尝试在尽可能少的数据库请求上运行查询并缓存最常用的查询。使用批处理方法显着减少请求处理时间是很常见的。
您使用哪种 ORM 从数据库检索数据?如果您使用 NHibernate,请参阅这篇文章,了解如何使用 Future, 多条件 1, 多标准 2 和多查询。
问候。
If you are concerned about performance you should also try to run your queries on as few DB requests as possible and cache the most used queries. It is very common to reduce significantly the request process time using batch approachs.
Which ORM do you use to retrieve data from DB? If you use NHibernate, see this post about how to use Future, Multi Criteria 1, Multi Criteria 2 and Multi Query.
Greetings.