在 LINQ 中使用 Foreach 的性能问题
我正在使用 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 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
Linq to SQL/Linq to Entities 使用延迟执行模式。一旦您调用
For Each
或任何其他间接调用GetEnumerator
的内容,您的查询就会被转换为 SQL 并针对数据库执行。诀窍是确保在此之前您的查询已完全正确地定义。使用
Where(...)
和其他 Linq 过滤器来尽可能减少查询将检索的数据量。在调用数据库之前,这些过滤器会内置到单个查询中。Linq to SQL/Linq to Entities 也都使用延迟加载。如果您有相关实体(例如销售订单 --> 有许多销售订单行 --> 有 1 个产品),则查询将不会返回它们,除非它知道需要这样做。如果你做了这样的事情:
你会得到糟糕的性能,因为在调用 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 callsGetEnumerator
, 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:
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.如果对
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 originalIList<Employee>
query.