在 LINQ 中使用 Foreach 的性能问题

发布于 2024-11-04 11:37:01 字数 354 浏览 0 评论 0原文

我正在使用 IList 通过使用 linq 获得超过 5000 条记录,这可能会更好吗? empdetailsList 有 5000 个

示例:

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

上面的示例需要花费大量时间才能迭代每个 empdetails,其中我需要获取相应的费用列表。

有人建议我该怎么做吗?

I am using an IList<Employee> where i get the records more then 5000 by using linq which could be better? empdetailsList has 5000

Example :

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

The above example takes a lot of time in order to iterate each empdetails where i need to get corresponding fees list.

suggest me anybody what to do?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

没企图 2024-11-11 11:37:01

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

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

Linq to SQL/Linq to Entities 也都使用延迟加载。如果您有相关实体(例如销售订单 --> 有许多销售订单行 --> 有 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 个。

为了避免此问题,如果您知道需要相关实体,请使用实体框架中的 Include() 方法。如果您做对了,当您分析数据库活动时,您应该只会看到正在进行的单个查询,并且该查询检索到的每个项目都应该由您的应用程序用于某些用途。

Linq to SQL/Linq to Entities use a deferred execution pattern. As soon as you call For Each or anything else that indirectly calls GetEnumerator, that's when your query gets translated into SQL and performed against the database.

The trick is to make sure your query is completely and correctly defined before that happens. Use Where(...), and the other Linq filters to reduce as much as possible the amount of data the query will retrieve. These filters are built into a single query before the database is called.

Linq to SQL/Linq to Entities also both use Lazy Loading. This is where if you have related entities (like Sales Order --> has many Sales Order Lines --> has 1 Product), the query will not return them unless it knows it needs to. If you did something like this:

Dim orders = entities.SalesOrders

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

You will get awful performance, because at the time of calling GetEnumerator (the start of the For Each), the query engine doesn't know you need the related entities, so "saves time" by ignoring them. If you observe the database activity, you'll then see hundreds/thousands of database roundtrips as each related entity is then retrieved 1 at a time.

To avoid this problem, if you know you'll need related entities, use the Include() method in Entity Framework. If you've got it right, when you profile the database activity you should only see a single query being made, and every item being retrieved by that query should be used for something by your application.

月依秋水 2024-11-11 11:37:01

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

If the call to Details.GetFeeDetails(emp.Emplid); involves another round-trip of some sort, then that's the issue. I would suggest altering your query in this case to return fee details with the original IList<Employee> query.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文