Возникли проблемы при группировании столбцов в запросе Linq с несколькими объединениями - PullRequest
0 голосов
/ 11 июня 2019

У меня есть MVC ViewModel, через которую я хотел бы перейти к представлению Razor. В контроллере я создал контекст базы данных и соединил таблицы, используя Linq. После суммирования и группировки я получаю сообщение об ошибке:

Ошибка CS1061 «десятичное» не содержит определения для «GroupBy», и доступный метод расширения «GroupBy», принимающий первый аргумент типа «десятичный», не найден (вы пропустили директиву using или ссылку на сборку?

Я рассмотрел почти каждый пример переполнения стека и Google и не смог найти пример, который соответствовал бы структуре моего запроса. Кроме того, примеры MS очень тривиальны и не очень полезны.

Вот действие в контроллере:

public IHttpActionResult GetEmployeeReleasedAllocatedBonus(int eid)
    {
        var employeeReleasedAllocatedBonus =
            (from br in _context.BonusReleases
                join emp in _context.Employees
                    on new
                    {
                        br.EmployeeID,
                        empID = br.EmployeeID
                    } equals new
                    {
                        emp.EmployeeID,
                        empID = eid
                    }
                join job in _context.Jobs on br.JobID equals job.JobID
                join bonus in _context.Bonus
                    on new
                    {
                        br.JobID,
                        empID = br.EmployeeID
                    }
                    equals new
                    {
                        bonus.JobID,
                        empID = bonus.EmployeeID
                    }
                select new EmployeeAllocatedReleasedBonusViewModel()
                {
                    AllocatedToEmployee = br.Amount, AllocatedPercentage = bonus.Amount * 100
                    ,
                    JobNumber = job.JobNumber, JobDescription = job.JobDescription

                })
            .ToList()
            .Sum(s => s.AllocatedToEmployee)
            .GroupBy(g => new {g.JobNumber, g.JobDescription, g.AllocatedPercentage});

        return Ok(employeeReleasedAllocatedBonus);
    }

Стоит отметить, что тип данных AllocatedPercentage является десятичным. Тем не менее, я попытался изменить его на строку, но сообщение об ошибке остается.

Также пытался использовать групповые функции прямо перед .ToList (), но это тоже не сработало.

Ответы [ 2 ]

0 голосов
/ 11 июня 2019

Комментарий Харальда был ключевым - после ToList () у меня был список.Поэтому я сделал шаг назад и сказал, что если я сначала помещу результаты в анонимный объект.Затем выполните группировку, а затем сумму, поместив окончательный результат в модель представления.Это сработало.Вот ответ.

var employeeReleasedAllocatedBonus =
            (from br in _context.BonusReleases
                join emp in _context.Employees
                    on new
                    {
                        br.EmployeeID,
                        empID = br.EmployeeID
                    } equals new
                    {
                        emp.EmployeeID,
                        empID = eid
                    }
                join job in _context.Jobs on br.JobID equals job.JobID
                join bonus in _context.Bonus
                    on new
                    {
                        br.JobID,
                        empID = br.EmployeeID
                    }
                    equals new
                    {
                        bonus.JobID,
                        empID = bonus.EmployeeID
                    }
                select new 
                {
                    AllocatedToEmployee = br.Amount
                    ,AllocatedPercentage = bonus.Amount * 100
                    ,JobNumber = job.JobNumber
                    ,JobDescription = job.JobDescription
                })
                .GroupBy(g => new {g.JobNumber, g.JobDescription, g.AllocatedPercentage})
                .Select(t => new EmployeeAllocatedReleasedBonusViewModel
                {
                JobNumber = t.Key.JobNumber,
                JobDescription = t.Key.JobDescription,
                AllocatedPercentage = t.Key.AllocatedPercentage,
                AllocatedToEmployee = t.Sum(ae => ae.AllocatedToEmployee)
                });
0 голосов
/ 11 июня 2019

После ToList() у вас есть List<EmployeeAllocatedReleasedBonusViewModel>.

В Sum(s => s.AllocatedToEmployee) каждый s равен единице EmployeeAllocatedReleasedBonusViewModel.Очевидно, что EmployeeAllocatedReleasedBonusViewModel имеет свойство AllocatedToEmployee, которое, вероятно, имеет тип decimal.Это может быть суммировано в один десятичный знак.

Результат Sum (десятичный знак) является вводом вашего GroupBy.Есть ли у типа decimal метод GroupBy?Конечно, это не так!

Увы, вы забыли сообщить нам свои требования.Трудно извлечь их из кода, который не выполняет то, что вы хотите.

Мне кажется, что у вас есть два отношения один ко многим:

  • Employeesиметь ноль или более BonusReleases.Каждый BonusRelease принадлежит ровно одному Employee с использованием внешнего ключа
  • Jobs, имеющего ноль или более BonusReleases.Каждый BonusRelease принадлежит ровно одному Job.

Теперь, что вы хотите: хотите ли вы все JobNumbers и JobDescriptions всех Jobs с общим количеством их AllocatedPercentage?Я не уверен, что Employees делает в этом запросе.

Всякий раз, когда вы хотите, чтобы элементы с их подэлементами, например, школы с их учениками, клиенты с их заказами, заказы с их линиями заказов,используйте GroupJoin.Если вы хотите наоборот, учащийся школы, в которой он учится, заказ с клиентом, который разместил заказ, используйте Join.

var result = dbContext.Jobs.GroupJoin(dbContext.BonusReleases,
    job => job.Id,                       // from every Job take the primary key
    bonusRelease => bonusReleas.JobId,   // from every BonusRelease take the foreign key

    // parameter ResultSelector: take every Job with all its BonusReleases to make a new:
    (job, bonusReleasesOfThisJob) => new
    {
        JobNumber = job.JobNumber,
        JobDescription = job.JobDescription

        // do you want the total of all allocated percentages?
        TotalAllocatedPercentages = bonusReleasesOfThisJob
            .Select(bonus => bonus.Amount)
            .Sum(),
            // do something to make it a percentage

         // or do you want a sequence of allocated percentages?
         TotalAllocatedPercentages = bonusReleasesOfThisJob
            .Select(bonus => bonus.Amount)
            .ToList(),
});

Или вы хотите JobNumber / JobDescription /Общий выделенный бонус на одного сотрудника?

var result = dbContext.Employees.GroupJoin(dbContext.BonusReleases,
    employee => employee.Id,    // from every Employee take the primary key
    bonus => bonus.EmployeeId,  // from every BonusRelease take the foreign key

    (employee, bonusesOfThisEmployee) => new
    {
        // Employee properties:
        EmployeeId =  employee.Id,
        EmpoyeeName = employee.Name,

        // for the jobs: Join the bonusesOfThisEmployee with the Jobs:
        Jobs = dbContext.Jobs.GroupJoin(bonusOfThisEmployee,
            job => job.Id,
            bonusOfThisEmployee => bonusOfThisEmployee.JobId,

            (job, bonusesOfThisJob) => new
            {
                Number = job.Id,
                Description = job.Description,
                TotalBonus = bonusOfThisJob.Select(bonus => bonus.Amount).Sum(),
            }),
   });               
...