多次调用ToList会影响性能吗?

时间:2015-10-30 04:25:30

标签: c# linq

我经常看到调用ToList会使查询每次都执行。我有点困惑。那么在这种情况下,第二次调用ToList会使查询多次执行吗?在什么情况下查询会多次执行?

//This gets from database and ToList is already called here
List<Customer> Customers = GetCustomersFromDataBase();

//ToList is called here again
List<Customer> FilteredCustomers = (from c in Customerswhere c.id == 1c).ToList();

修改

我刚刚提供了这个代码示例,以了解ToList的真正作用。我没有这样实现它。 此外,我进行存储过程调用以从db返回客户,并从返回的数据表中创建客户列表。

3 个答案:

答案 0 :(得分:7)

ToList上拨打ToArray(或AsEnumerableIQueryable等)即可执行查询。之后,您使用的任何LINQ表达式都将在内存列表中运行。

例如,您的代码:

List<Customer> Customers = GetCustomersFromDataBase();

这将导致ListCustomer个对象代表数据库记录。该列表现在独立于用于从数据库中获取结果的查询,但仍需要从数据库中提取Customer对象中的链接记录。

然后当你这样做时:

List<Customer> FilteredCustomers = (from c in Customers where c.id == 1c).ToList();

这不是在数据库上运行,而是在从前一个语句返回的内存中的结果上运行。在这种情况下,您不会多次查询数据库。

影响效果的地方是指您有一个IQueryable对象,您可以多次直接调用ToList。在ToList上对IQueryable的每次调用都将导致对数据库的调用,所有伴随对象都会在后台跟踪。通常,这是您要避免的,尽管在枚举结果之前对查询进行额外过滤可能会导致更好的性能,如果查询选择的记录总数很大并且过滤器会拉取数据的小子集。

答案 1 :(得分:3)

在您的方案中,查询只执行一次。

下面:

List<Customer> FilteredCustomers = (from c in Customers where c.id == 1c).ToList();

此行仅基于变量Customers进行过滤,该变量是由ToList()填充的客户表的副本。

答案 2 :(得分:1)

检查Enumerable.ToList()的源代码(google for it) Enumerable.ToList()

public static List<TSource> ToList<TSource>(this IEnumerable<TSource> source)
{
    if (source == null) throw Error.ArgumentNull("source");
        return new List<TSource>(source);
}

所以是ToList()。ToList(),是一种浪费,一个列表被创建,第一个ToList中的所有(引用)元素都被复制到第二个,导致新的内存要分配,第一个列表是垃圾回收,导致内存被释放。