sunil kumar meena Ответов: 1

Запрос Linq для возврата двух лучших результатов, когда есть какой-то конфликт, не работает?


Я пытался сделать простую вещь: сформировать коллекцию сотрудников, из которых я хочу получить два лучших списка максимальных сотрудников. Но помните, что может быть несколько сотрудников с одинаковой зарплатой, поэтому я хочу, чтобы все они попадали в максимальный диапазон двух зарплат. ниже приведена моя коллекция, которую я использую:
List<Employee> Employees = new List<Employee>
            {
new Employee {EmployeeID = 1,EmployeeName  ="A", Department ="Dept1", Salary = 10000 },
new Employee {EmployeeID = 5,EmployeeName  ="A1", Department ="Dept2", Salary = 12000 },
new Employee {EmployeeID = 2,EmployeeName ="B", Department ="Dept1", Salary = 20000 },
new Employee {EmployeeID = 3,EmployeeName ="C",  Department ="Dept1", Salary = 20000 },
new Employee {EmployeeID = 6,EmployeeName ="B1", Department ="Dept2", Salary = 4500 },
new Employee {EmployeeID = 4,EmployeeName="D",  Department ="Dept1", Salary = 30000 },
            };

А класс сотрудников-это:
public class Employee
    {
        public int EmployeeID { get; set; }
        public string EmployeeName { get; set; }
        public string Department { get; set; }
        public long Salary { get; set; }
    }

а ниже мой запрос:
var result1 = from x in Employees
                    group x by x.Salary into g
                    from y in g.OrderBy(x=>x.Salary).Take(2)
                    select new { y.EmployeeID };

            foreach (var item in result1)
            {
                Console.WriteLine(item.EmployeeID);
            }

То, что я пытаюсь сделать здесь, заключается в том, что сначала я группирую всех сотрудников на основе их заработной платы. Затем закажите эти группы и возьмите первые две группы, используя метод расширения TAKE, а затем распечатайте всех сотрудников, которые находятся в этих двух группах.

Но я не знаю, почему он печатает всех сотрудников; он даже не заказывает их. Может ли кто-нибудь поделиться некоторыми мыслями и сказать мне, что не так с этим запросом?

Что я уже пробовал:

Я пытался изменить положение порядка ПО и группировать, все еще получая те же результаты.

1 Ответов

Рейтинг:
7

Wendelius

Во-первых, это очень хорошо сформулированный вопрос с примерами данных, красиво сделано!

Одним из довольно простых способов может быть использование двух отдельных запросов, один из которых предназначен для получения максимальной зарплаты, а второй-для сотрудников, например

var topSal = from x in Employees
             group x by x.Salary into g
             orderby g.Key descending
             select new {
                TopSalary = g.Key
             };

var result1 = from x in Employees
              join s in topSal.Take(2) on x.Salary equals s.TopSalary
              select new { x.EmployeeID };

foreach (var item in result1) {
   Console.WriteLine(item.EmployeeID);
}

Это также может быть записано с помощью одного оператора, например
var result2 = from x in Employees
              join s in Employees.Select(x1 => x1.Salary).Distinct().OrderByDescending(x2 => x2).Take(2) on x.Salary equals s
              select new { x.EmployeeID };

foreach (var item in result2) {
   Console.WriteLine(item.EmployeeID);
}


Kornfeld Eliyahu Peter

Кроме того, чтобы быть точным ответом, это также очень хороший пример того, почему вы не должны писать SQL как часть своего кода...

Wendelius

:) Это очень верно.

sunil kumar meena

Но почему " из y в g. OrderBy(x= & gt;x.зарплата).Возьмите(2)" это не работает в моем запросе?

Wendelius

Take выполняется в другой фазе, которую вы ожидаете. Отдельная сгруппированная строка оценивается перед операцией взятия.

Взгляните на выполнение с помощью отладчика, пройдите исходный запрос построчно. Я верю, что это поможет вам увидеть, как проводится оценка :)