【问题标题】:Having trouble grouping columns in Linq query with multiple joins在具有多个连接的 Linq 查询中对列进行分组时遇到问题
【发布时间】:2019-06-11 01:21:29
【问题描述】:

我有一个想要传递给 Razor 视图的 MVC ViewModel。在控制器中,我创建了一个数据库上下文并使用 Linq 将表连接在一起。汇总和分组后,出现错误:

错误 CS1061 'decimal' 不包含 'GroupBy' 的定义,并且找不到接受第一个参数类型为 'decimal' 的可访问扩展方法 '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() 之前使用组功能,但这也不起作用。

【问题讨论】:

  • 我想知道bonus.Amount * 100 是否导致了问题。你的select new 应该是这样的:select new { br, bonus, job } 比在ToList() 之后返回字段并进行计算。
  • .Sum(s => s.AllocatedToEmployee) 会返回一个十进制值,你怎么再分组呢。
  • Harisyam,我会为您提供帮助,但您的评论不是很有建设性。
  • 嗨 Flavio,我删除了 *100 但错误仍然存​​在。从我收集的问题来看,我将 SUM 的结果(即小数)传递给 GroupBy - 它不包含 GroupBy 的方法。

标签: linq model-view-controller group-by controller viewmodel


【解决方案1】:

ToList() 之后你有一个List<EmployeeAllocatedReleasedBonusViewModel>

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

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

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

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

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

现在你想要什么:你想要所有JobNumbersJobDescriptions 中的所有Jobs 以及它们的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(),
            }),
   });               

【讨论】:

  • 嗨哈拉尔。谢谢你的帮助。我在这里上传了 ER 图pasteboard.co/IiVK7IO.png 分配的百分比是固定的每个员工每个工作。员工可以为每项工作获得多个奖金发放。假设工作持续 3 年,员工可能会在 2016、2017、2018 年等收到付款。我只想查看释放的总金额 - 每名员工每份工作。因此,以下是分组依据字段:职位编号、职位描述、员工全名、分配百分比。要求和的字段:AllocatedToEmployee。对于你的问题,应该是后者。
  • 感谢您的指导。我会阅读关于加入群组的内容。根据您的解释,在这种情况下使用它是有意义的。
【解决方案2】:

Harald 的评论很关键 - 在 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)
                });

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2023-01-31
    • 1970-01-01
    • 1970-01-01
    • 2023-03-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多