vaindil
vaindil

Reputation: 7864

Get top result in each parent property in Entity Framework

I'm trying to select the employees with the most reports in each department. I can't figure out how to do this though with LINQ in Entity Framework. I'm using EF Core, but the answer should be the same as EF 6 so an answer for either will work. I know I'll need to use .Distinct(), but I'm not sure how to use it properly.

How can I get the employee in each department with the most reports? The query should return a list (or queryable) of employees.

public class Employee
{
    public long Id { get; set; }
    public string Name { get; set; }

    public long DepartmentId { get; set; }
    public Department Department { get; set; }

    public ICollection<Report> Reports { get; set; }
}

public class Department
{
    public long Id { get; set; }
    public string Name { get; set; }

    public ICollection<Employee> Employees { get; set; }
}

This is what I started with, but I'm not sure if it's even the right way to begin.

var employees = _context.Employees
    .OrderByDescending(e => e.Reports.Count)
    // ?

Upvotes: 1

Views: 181

Answers (3)

Gert Arnold
Gert Arnold

Reputation: 109205

You should start the query at the department level. Within each department, get its employee with the highest report count:

var topEmpPerDep = _context.Departments
    .Select(dep => new
    {
        Department = dep.Name,
        Employee = dep.Employees.OrderByDescending(e => e.Reports.Count)
           .FirstOrDefault().Name
    });

Upvotes: 1

jdweng
jdweng

Reputation: 34421

Try this :

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace ConsoleApplication1
{
    class Program
    {
        static void Main(string[] args)
        {
            var results = Department.departments.Select(x => new {
                deptmentName = x.Name,
                maxEmployeeReports = x.Employees.Select(y => new { name = y.Name, count = y.Reports.Count, employee = y }).OrderByDescending(z => z.count).FirstOrDefault()
            }).ToList();
        }
    }
    public class Employee
    {
        public long Id { get; set; }
        public string Name { get; set; }

        public long DepartmentId { get; set; }
        public Department Department { get; set; }

        public ICollection<Report> Reports { get; set; }
    }

    public class Department
    {
        public long Id { get; set; }
        public string Name { get; set; }

        public ICollection<Employee> Employees { get; set; }
        public static List<Department> departments = new List<Department>();
    }
    public class Report
    {
    }
}

Upvotes: 0

YuvShap
YuvShap

Reputation: 3835

Just take from each department the employee with the most reports:

var employees = _context.Departments.Select(department => 
                  department.Employees.OrderByDescending(employee => employee.Reports.Count).FirstOrDefault()).ToList();

Upvotes: 1

Related Questions