首页 > 解决方案 > 在具有多个连接的 Linq 查询中对列进行分组时遇到问题

问题描述

我有一个想要传递给 Razor 视图的 MVC ViewModel。在控制器中,我创建了一个数据库上下文并使用 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() 之前使用组功能,但这也不起作用。

标签: linqmodel-view-controllergroup-bycontrollerviewmodel

解决方案


ToList()你拥有一个List<EmployeeAllocatedReleasedBonusViewModel>.

Sum(s => s.AllocatedToEmployee),每一个s都是一个EmployeeAllocatedReleasedBonusViewModel。显然 aEmployeeAllocatedReleasedBonusViewModel有一个AllocatedToEmployee可能是十进制类型的属性。这可以加到一位小数。

Sum(小数)的结果是您的输入GroupBy。类型十进制有方法GroupBy吗?当然不是!

唉,你忘了告诉我们你的要求。很难从不符合您要求的代码中提取它们。

在我看来,您有两个一对多的关系:

  • Employees有零个或多个BonusReleases。每个使用外键BonusRelease完全属于一个Employee
  • Jobs有零个或多个BonusReleases。每一个都BonusRelease属于一个Job

现在你想要什么:你想要 allJobNumbersJobDescriptionsallJobs和他们的总数AllocatedPercentage吗?我不确定Employees在这个查询中做什么。

每当您想要带有子项目的项目时,例如带有学生的学校、带有订单的客户、带有 OrderLine 的订单,请使用 GroupJoin。如果您希望反过来:学生与他就读的学校,与下订单的客户订购,使用加入。

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(),
            }),
   });               

推荐阅读