简体   繁体   中英

Using Entity Framework, how do I access the number of employees (one entity) corresponding to each office (another entity)?

I have two entities: an employee entity and an office entity. There is a one-many relationship between these two entities -- that is, one office may have many employees but each employee only has one office.

I am using Entity Framework 6 to work on a project. I am currently using this tutorial to learn how to create a simple web application using Entity Framework. I have changed the code a bit to play around with my own entities.

Right now I am trying to have the 'about' page of my application display the number of employees that are at each office. In other words, I'm trying to create a two-column table where the first column contains all the locations of the offices, and the second column contains the corresponding number of employees at each location. I believe this means I must pull data from each database (table?), however I don't know how to get the number of employees for each office. Getting the total number is easy. I can just write the following query:

NumOfEmployees = locationGroup.Count()

where locationGroup is the variable grouping the data from the two entities, and NumOfEmployees is a public int from the LocationGroup class. Here is the block of code I am currently using (most of it coming from the tutorial -- I have commented the parts I added).

public ActionResult About()
{
    IQueryable<LocationGroup> data = from employee in db.Employees
            group employee by employee.FirstName into locationGroup

            //added the second pull of data from the other db
                                    from office in db.Offices
            group office by office.Location into locationGroup
            select new LocationGroup()
            {
                Location = locationGroup.Key,
                NumOfEmployees = locationGroup.Count() //modified this from original
            };
    return View(data.ToList());
}

As you can see from the code, the

NumOfEmployees = locationGroup.Count()

doesn't do what I want it to do. I want it to return the number of employees for each office location, but instead it just returns the total number of employees and writes that for each office location. In my Employee.cs class, the Employee entity has an OfficeID to which it can refer:

public class Employee
{
    public int EmployeeID { get; set; }
    public int OfficeID { get; set; }
    public string FirstName { get; set; }
    public string LastName { get; set; }
    public int PhoneNum { get; set; }
    public DateTime DoB { get; set; }
    public DateTime HireDate { get; set; }
    public string JobTitle { get; set; }
    public int Salary { get; set; }

    public virtual Office Office { get; set; }
}

So I was trying to access that OfficeID and use a conditional statement so it only counts those employees for which the corresponding OfficeID. I have looked around for a solution and I can't tell if I can do this in one line with a particular aggregate query, or if I need to create a loop that counts the employees for each office. The problem is I don't know the syntax for accessing the number of each employees that each office has. I don't even know how I would access the properties of the offices + employees inside the select clause

select new AddressGroup()

in the About() method above, nor if I need to. Any help with the About() method above would be much appreciated.

Edit: I have added the Office class below:

public class Office
{
    public int ID { get; set; }
    public string Location { get; set; }
    public string BusinessName { get; set; }

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

Here is the easiest way on your database, doing the grouping and counting there:

var result=db.Offices
  .Select(o=>new OfficeEmployeeCount{
    OfficeName=o.BusinessName,
    EmployeeCount=o.Employees.Count()});

Then create your class OfficeEmployeeCount:

public class OfficeEmployeeCount
{
  public string OfficeName {get;set;}
  public int EmployeeCount {get;set;}
}

And access it in your view like so:

@model IQueryable<OfficeEmployeeCount>
<table>
<thead><tr><th>Office Name</th><th>Employees</th></tr></thead>
@foreach(var office in Model)
{
  <tr>
    <td>@office.OfficeName</td>
    <td>@office.EmployeeCount</td>
  </tr>
}
</table>

or just feed the offices directly from your controller:

var result=db.Offices.Include(o=>o.Employees);
return View(result);

Then in your view, you can access in like so:

@model IQueryable<Office>
<table>
<thead>
 <tr>
  <th>Office Name</th>
  <th>Employee Count</th>
  <th>Employee Names</th>
  <th>Employees</th>
 </tr>
</thead>
@foreach(var office in Model)
{
  <tr>
    <td>@office.BusinessName</td>
    <td>@office.Employees.Count()</td>
    <td>@String.Join(",",office.Employees.Select(e=>e.FirstName + " " + e.LastName))</td>
    <td>@foreach(var e in o.Employees)
    {
      @Html.ActionLink(e.FirstName + " " + e.LastName,"Details","Employees",new {ID=e.ID})
    }
    </td>
  </tr>
}
</table>

The first way is easiest on your database, especially if you have a large number of employees. The second way is more flexible in the view, such as if you want to then list the actual employees.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM