Проблема Performace с использованием Foreach в LINQ - PullRequest
1 голос
/ 28 апреля 2011

Я использую IList<Employee>, где я получаю записи более 5000, используя linq, что может быть лучше? Список empdetailsList имеет 5000

Пример:

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

Приведенный выше пример занимает много времени для итерации каждого empdetails, где мне нужно получить соответствующий список сборов.

подскажите кто-нибудь, что делать?

Ответы [ 2 ]

3 голосов
/ 28 апреля 2011

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() в Entity Framework. Если вы правильно поняли, при профилировании активности базы данных вы должны увидеть только один запрос, и каждый элемент, извлекаемый этим запросом, должен быть использован вашим приложением.

2 голосов
/ 28 апреля 2011

Если вызов Details.GetFeeDetails(emp.Emplid); связан с каким-то другим циклом туда-обратно, то это проблема. В этом случае я бы предложил изменить ваш запрос, чтобы он возвращал сведения о плате с исходным запросом IList<Employee>.

...