0

Need help in writing LINQ Query to get count of employee based on department.

Department Model

public class Department
{
    public int Id { get; set; }
    public string Name { get; set; }
    public List<Employee> Employees { get; set; }
}

Employee Model

public class Employee
{
    public int Id { get; set; }
    public string Name { get; set; }
    public int DepartmentId { get; set; }
    public Department Department { get; set; }
}

MyViewModel

public class MyViewModel
{
    public string Department { get; set; }
    public int count { get; set; }
}

LINQ Query

    public ActionResult shows()
    {
        //one department can have many employees and one employee can only be parrt of one department
        // below LINQ query fetches the count of employees belonging to each department
        var x = _context.Employees.Include("Department").GroupBy(e => e.DepartmentId)
     .Select(y=> new MyViewModel{
             Department= y.Key, // ERROR HERE AS Cannot type cast string to integer
            count = y.Count()               
        }).ToList();
     // code removed for brevity
        return Content("x");
    }

Output Expected

Department                 Count (or employees)

Human Resource               10

Information Tech              5

Question How to write a LINQ Query to get the output as above. Please guide me.

7
  • Department= y.First().Department.Name, (assumes Department contains a property named Name) Commented Jul 22, 2017 at 7:42
  • @StephenMuecke: I am really sorry, but I could not follow you. In this tutorial "youtube.com/…" at 1:57 minute its working fine for the tutor. Commented Jul 22, 2017 at 7:47
  • Change Department= y.Key to Department= y.First().Department.Name Commented Jul 22, 2017 at 7:48
  • And that tutorial is using GroupBy(e => e.Department.Name) in which case you can use Department= y.Key, Commented Jul 22, 2017 at 7:49
  • I got error as the "first" cannot be used a final query operation" Commented Jul 22, 2017 at 7:49

4 Answers 4

1

You have 2 options for modifying your query. I am assuming your Department model contains a property string Name which you want to assign to the Department property of your view model.

  1. Get the first Department in the grouped collection and assign its Name property to your view models Department property. Note that you need to add .ToList() before .GroupBy() so that the first part of the query is executed before grouping

    var x = _context.Employees
        .Include("Department")
        .ToList()
        .GroupBy(e => e.DepartmentId)
        .Select(y => new MyViewModel
        {
             Department = y.First().Department.Name,
             count = y.Count()               
        }).ToList();
    
  2. Change the .GroupBy() expression to group by the Name property of the Department property

    var x = _context.Employees
        .Include("Department")
        .GroupBy(e => e.Department.Name)
        .Select(y=> new MyViewModel
        {
            Department = y.Key,
            count = y.Count()               
        }).ToList();
    
Sign up to request clarification or add additional context in comments.

9 Comments

Kindly do explain why even after grouping by ID (logically wrong) we still get the correct output.
Caution here grouping only by the name property of the department should work appropriately only if you have an unique constraint on the Name column ensuring you have unique department names. If you have duplicate department names for some reason you'll get the sum of employees in those lets say two departments. The best thing will be to group by Id AND Name, see my answer.
@MihailShishkov: Makes perfect sense. I am just doing it for a learning purpose, but I will pay heed to what you are telling. Thanks a ton!. I will try your solution too. :)
@MihailShishkov, You answer is grouping by the Employees DepartmentId and Employees Name (not Department Name) which is not what OP wants
In option 1 you'll have to retrieve every employee from the database which is bad. What if there are thousands of employees? Effectively what you need @Unbreakable is this SQL to be executed on the server SELECT DepId, Name, COUNT(1) AS EmplCount FROM Employees GROUP BY DepId, Name
|
1
public ActionResult shows()
    {
        //one department can have many employees and one employee can only be parrt of one department
        // below LINQ query fetches the count of employees belonging to each department
        var x = _context.Employees.Include("Department").GroupBy(e => new { e.DepartmentId, e.Department.Name})
     .Select(y=> new MyViewModel{
             Department= y.Key.Name
            count = y.Count()               
        }).ToList();
     // code removed for brevity
        return Content("x");
    }

the key here is to group by DepartmentId AND Name

Comments

0

Try it like this:

public ActionResult shows()
{
    //one department can have many employees and one employee can only be parrt of one department
    // below LINQ query fetches the count of employees belonging to each department
    var x = _context.Employees.Include("Department").GroupBy(e => e.DepartmentId)
 .Select(y=> new MyViewModel{
         Department= y.Key.DepartmentName, // or whatever property you have for storing the name
        count = y.Count()               
    }).ToList();
 // code removed for brevity
    return Content("x");
}

Comments

0

you can use this code :

using System.Linq;
using System.Web.Mvc;
using MvcApplication1.Models;

namespace MvcApplication1.Controllers
{
     
     public class HomeController : Controller
     {
          public ActionResult Index()
          {
               var dataContext = new MovieDataContext();
               int count = (from row in dataContext.Movies
                    where row.IsEnquiry == true
                 select row).Count();
               ViewBag.ItemCount = count;
               return View();
          }
     }
}

1 Comment

Explain your answer

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.