Loading...
msmilkoff avatar msmilkoff 338 Точки

[Introduction to EF] - Problem {5} - Departments with more than 5 employees - Въпрос относно авторското решение.

В авторското решение на задачата забелязах две неща, които (според това което аз съм чел) са супер грешни.

  1.   Заявката се присвоява на променлива от тип IEnumerable.
    По правило не трябва ли винаги да се работи с IQueryable? Така заявката, която се изпраща към базата е доста по оптимизирана, защото се възползваме от Linq-to-Entities. И по-важно, Extension методите изглеждат същите, но не са. Методите върху IEnumerable, очакват като параметър Func<нещо си>, докато при IQueryable очакват Expression<Func<нещо си>>. Няма нужда да се обяснява, че разликата е огромна.
     
  2. Вътрешният Foreach итерира по department.Employees. 
    Няма ли опасност да се стигне до т. нар. "Select N + 1" проблем? Накратко - ще се генерира една заявка за департамента и след това по една за всеки служител в него, което не е готино от гледна точка на performance.
    Не е ли по добър вариантът:
    var departments = db.Departments
                    .Where(d => d.Employees.Count > 5)
                    .OrderBy(d => d.Employees.Count)
                    .Select(d => new
                    {
                        Name = d.Name,
                        Manager = d.Employee.FirstName,
                        DepEmployees = d.Employees
                    });
    
                foreach (var department in departments)
                {
                    Console.WriteLine($"{department.Name} {department.Manager}");
    
                    var employees = department.DepEmployees;
                    foreach (var employee in employees)
                     // ......

     

Ако някой с по-дълбоки познания по EF разясни дали наистина е така или пък аз се бъркам - ще е супер.

1
Databases Advanced - Entity Framework 31/10/2016 15:08:16
RFilipov avatar RFilipov 136 Точки

Не се бъркаш.

Единият вариант е проекция със Select.

Другият е така нареченият eager-loading със Include:

var departments = db.Departments
.				.Include("Employees")
                .Where(d => d.Employees.Count > 5)
                .OrderBy(d => d.Employees.Count)
                .Select(d => new
                {
                    Name = d.Name,
                    Manager = d.Employee.FirstName,
                    DepEmployees = d.Employees
                });

Авторското решение е N + 1 това можеш да го видиш във SQL Profiler.

3
val4o89 avatar val4o89 240 Точки

Като гледам авторското решение и на база знанията, които се очаква да имаме до момента, а не на програмист с 10г. опит smiley

След някой друг урок ще правим нещата, както сте ги чели.

-1
stambi4a avatar stambi4a 126 Точки

Най- добрият начин е native. В това видео се прави  измерване и се вижда,че native заявките са много по- бързи от другите. Select e за предпочитане пред include, защото в една таблица може да имаш 20, 30 и повече колони,при положение, че често ти трябват само няколко  което генерира излишен трафик по мрежата и в паметта. Тази статия разглежда доста подробно  performance-a в EF.

1
Можем ли да използваме бисквитки?
Ние използваме бисквитки и подобни технологии, за да предоставим нашите услуги. Можете да се съгласите с всички или част от тях.
Назад
Функционални
Използваме бисквитки и подобни технологии, за да предоставим нашите услуги. Използваме „сесийни“ бисквитки, за да Ви идентифицираме временно. Те се пазят само по време на активната употреба на услугите ни. След излизане от приложението, затваряне на браузъра или мобилното устройство, данните се трият. Използваме бисквитки, за да предоставим опцията „Запомни Ме“, която Ви позволява да използвате нашите услуги без да предоставяте потребителско име и парола. Допълнително е възможно да използваме бисквитки за да съхраняваме различни малки настройки, като избор на езика, позиции на менюта и персонализирано съдържание. Използваме бисквитки и за измерване на маркетинговите ни усилия.
Рекламни
Използваме бисквитки, за да измерваме маркетинг ефективността ни, броене на посещения, както и за проследяването дали дадено електронно писмо е било отворено.