从不同的表中获取数据并显示在 View Index 中

Take data from different tables and display it in View Index

我有 2 个表 Job_tableEmployee_table。我想在 Employee_table 的索引视图中显示来自 Job_tableemp_id 和来自 Employee_table 的相应 emp_name

就此而言,我创建了一个 ViewModel EmployeeViewModel 并将我的操作结果的索引视图与 IEnumerable<EmployeeViewModel> 绑定。 EmployeeViewModel 的定义如下所示:

public class EmployeeViewModel
{
    public int EmployeeId { get; set; }
    public string EmployeeName  { get; set; }
    public string JobName { get; set; }
    //..Other memberVariables..
}

我的模特:

    public class Employee
    {
        [Key]
        [DatabaseGenerated(DatabaseGeneratedOption.Identity)]
        public int EmployeeId { get; set; }
        public string EmployeeName { get; set; }
        public string Address { get; set; }
        public virtual ICollection<Job> Jobs { get; set; }
    }

还有 WorkTable,为方便起见,将其重命名为 Job:

public class Job
{
    [Key]
    [DatabaseGenerated(DatabaseGeneratedOption.Identity)]
    public int JobId { get; set; }
    public string JobName { get; set; }
    public JobCategory JobCategory { get; set; }
    public int EmployeeId { get; set; }
    public virtual ICollection<Employee> Employees { get; set; }
}

在我的索引操作中,我通过连接两个表创建了一个结果集,将其绑定到 IEnumerable<EmployeeViewModel> 并将其作为模型传递给视图。正如我之前提到的,View 应该接收一个 IEnumerable<EmployeeViewModel> 类型的模型,所以我需要查询我的实体,它应该是这样的:

public ActionResult Index()
{
    //..something like this..this is IQueryable..
    //...convert this to IEnumerable and send this as the model to ..
    //..the Index View as shown below..here you are querying your own tables, 
    //.. Employee and Job,and binding the result to the EmployeeViewModel which
    //.. is passed on to the Index view.
    IEnumerable<EmployeeViewModel> model=null;
    model = (from c in db.Employees
                join q in db.Jobs on c.EmployeeId equals q.EmployeeId
                 from q in jobs.DefaultIfEmpty()
                 group new { q, c } by c into grp
                select new EmployeeViewModel
                {
                    EmployeeId = grp.Key.EmployeeId,
                    EmployeeName = grp.Key.EmployeeName,

                });

    return View(model);
}

我想显示这样的结果:

|Employee 1|
|----------|
| Job 1    |
| Job 2    |

|Employee 2|
|----------|
| Job 3    |
| Job 4    |
| Job 5    |

但现在我的结果是

|Employee 1|  |Employee 1|
|----------|  |----------|
| Job 1    |  | Job 2    |

|Employee 2|  |Employee 2|  |Employee 2|
|----------|  |----------|  |----------|
| Job 3    |  | Job 4    |  | Job      |

如何删除重复项?

这里需要的是数据库世界里的LEFT JOIN。如何将两个 table 加入 SQL 有多种可能性。每个变体都会产生不同的结果。默认的 JOIN 是一个 INNER 连接,这意味着结果集中的每个实体都存在于 both tables。 LEFT 连接意味着实体可以存在于两个 table 中,但不能存在。如果第二个table中不存在,则返回空结果集。有两个 table 的例子 PersonJob:

|Table Person  |   |Table Job       |
| Id | Name    |   | Id | Job       |
|----|---------|   |----|-----------|
| 1  | John    |   | 1  | Astronaut |
| 2  | William |   | 3  | Cashier   |

默认的 LINQ 连接是 INNER 连接:

var r =  from p in Person
            join j in Jobs on p.Id equals j.Id
            select ...

将交付此结果集:

| INNER JOIN  RESULT    |
| Id | Name | Job       |
|----|------|-----------|
| 1  | John | Astronaut |

LEFT 联接在 LINQ 中将如下所示:

var r =  from p in Person
            join j in Jobs on p.Id equals j.Id into jobs
            from subjob in jobs.DefaultIfEmpty()
            select ...
                Job = subjob != null ? subjob.Job : "no job"
                 ...

现在结果集如下所示:

| LEFT JOIN  RESULT        |
| Id | Name    | Job       |
|----|---------|-----------|
| 1  | John    | Astronaut |
| 2  | William | no job    |

可以在本文 A visual explanation of SQL joins.

中找到很好的视觉解释

通常 LINQ 中的默认 join 是 INNER JOIN,因此只会选择匹配的实体(在两个 tables 中)。你可以做一个 LEFT JOIN with LINQ using a second from with DefaultIfEmpty:

model = (from e in db.Employees
            join j in db.Jobs on e.EmployeeId equals j.EmployeeId into jobs
            from subjob in jobs.DefaultIfEmpty()
            select new EmployeeViewModel
            {
                EmployeeId = e.EmployeeId,
                EmployeeName = e.EmployeeName,
                JobName = subjob != null ? subjob.JobName : "no job entry"
            }).Distinct();

可以在 MSDN 上找到来自 Microsoft 的很好的 LINQ 介绍:101 LINQ samples


分组依据可能如下所示:

model = (from e in db.Employees
            join j in db.Jobs on e.EmployeeId equals j.EmployeeId into jobs
            from subjob in jobs.DefaultIfEmpty()
            group e by e.EmployeeName into ge
            select new
            {
                Key = ge.Key,
                Data = ge
            });

foreach (var groupItem in model)
{
    foreach (var employeeViewModel in groupItem.Data)
    {
        // ...
    }
}