在LINQ中使用Foreach的性能问题

时间:2011-04-28 12:41:50

标签: linq linq-to-entities linq-to-objects

我正在使用IList<Employee>,我使用linq得到的记录超过5000,哪个更好? empdetailsList有5000

示例:

foreach(Employee emp in empdetailsList)
{
       Employee employee=new Employee();
   employee=Details.GetFeeDetails(emp.Emplid);
}

以上示例需要花费大量时间才能迭代我需要获得相应费用清单的每个细节。

建议我任何人做什么?

2 个答案:

答案 0 :(得分:3)

Linq to SQL / Linq to Entities使用延迟执行模式。只要您调用For Each或其他间接调用GetEnumerator的内容,就会将您的查询转换为SQL并对数据库执行。

诀窍是确保在此之前完全正确地定义您的查询。使用Where(...)和其他Linq过滤器尽可能减少查询将检索的数据量。在调用数据库之前,这些过滤器构建在单个查询中。

Linq to SQL / Linq to Entities也都使用延迟加载。如果您有相关实体(例如销售订单 - &gt;有许多销售订单行 - &gt;有1个产品),那么查询将不会返回它们,除非它知道它需要。如果你做了这样的事情:

Dim orders = entities.SalesOrders

For Each o in orders
   For Each ol in o.SalesOrderLines
      Console.WriteLine(ol.Product.Name)
   Next
Next

您将获得糟糕的性能,因为在调用GetEnumerator(For Each的开头)时,查询引擎不知道您需要相关实体,因此忽略它们“节省时间” 。如果您观察数据库活动,那么您将看到数百/数千个数据库往返,因为每次检索1个相关实体。

要避免此问题,如果您知道需要相关实体,请使用Entity Framework中的Include()方法。如果你做对了,当你描述数据库活动时,你应该只看到一个查询,并且该查询检索的每个项目都应该被你的应用程序用于某些东西。

答案 1 :(得分:2)

如果对Details.GetFeeDetails(emp.Emplid);的调用涉及某种往返的另一次往返,那就是问题所在。在这种情况下,我建议更改您的查询以使用原始IList<Employee>查询返回费用详细信息。