使用 Entity Framework,如何获取每个办公室(另一个实体)对应的员工(一个实体)的数量?

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

我有两个实体:员工实体和办公室实体。这两个实体之间存在一对多的关系——也就是说,一个办公室可能有很多员工,但每个员工只有一个办公室。

我正在使用 Entity Framework 6 来处理一个项目。我目前正在使用 this tutorial 来学习如何使用 Entity Framework 创建一个简单的 Web 应用程序。我稍微更改了代码以使用我自己的实体。

现在我正在尝试让我的应用程序的 'about' 页面显示每个办公室的员工人数。换句话说,我正在尝试创建一个双列 table,其中第一列包含办公室的所有位置,第二列包含每个位置的相应员工数。我相信这意味着我必须从每个数据库中提取数据(table?),但是我不知道如何获取每个办公室的员工人数。获得总数很容易。我可以编写以下查询:

NumOfEmployees = locationGroup.Count()

其中 locationGroup 是对来自两个实体的数据进行分组的变量,NumOfEmployees 是来自 LocationGroup class 的 public 整数。这是我目前正在使用的代码块(大部分来自教程——我已经评论了我添加的部分)。

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

从代码中可以看出,

NumOfEmployees = locationGroup.Count()

没有按我的意愿行事。我希望它 return 每个办公地点的员工人数,但它只是 return 员工总数并为每个办公地点写入。在我的 Employee.cs class 中,Employee 实体有一个可以引用的 OfficeID:

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; }
}

所以我试图访问该 OfficeID 并使用条件语句,因此它只计算具有相应 OfficeID 的员工。我四处寻找解决方案,但我不知道我是否可以通过特定的聚合查询在一行中执行此操作,或者我是否需要创建一个循环来计算每个办公室的员工人数。问题是我不知道访问每个办公室的每个员工人数的语法。我什至不知道如何访问 select 子句

中办公室 + 员工的属性
select new AddressGroup()

在上面的 About() 方法中,如果我需要的话。如果您对上述 About() 方法有任何帮助,我们将不胜感激。

编辑:我在下面添加了 Office class:

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; }
}

这是在你的数据库上最简单的方法,在那里进行分组和计数:

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

然后创建您的 class OfficeEmployeeCount:

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

然后像这样在您的视图中访问它:

@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>

或者直接从您的控制器向办公室提供信息:

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

那么在你看来,你可以这样访问:

@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>

第一种方法在您的数据库上最简单,尤其是当您有大量员工时。第二种方式在视图中更灵活,比如如果你想再列出实际员工。