从不同的表中获取数据并在查看索引

时间:2015-07-19 07:11:31

标签: c# sql-server asp.net-mvc linq-to-sql

我有2个表Job_tableEmployee_table。我想在emp_id的索引视图中显示来自Job_table的{​​{1}}和来自emp_name的相应Employee_table

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

IEnumerable<EmployeeViewModel>

我的模特:

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

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

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

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

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    |

如何删除重复项?

1 个答案:

答案 0 :(得分:0)

您需要的是数据库世界中的LEFT JOIN。如何在SQL中连接两个表有很多种可能性。每种变体都会产生不同的结果。默认的 JOIN INNER 连接,这意味着结果集中的每个实体都存在于两个表中。 LEFT 连接意味着实体可能存在于两个表中,但必须不存在。如果第二个表中不存在,则返回空结果集。一个包含两个表 Person Job 的示例:

|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中的默认连接是INNER JOIN,因此只会选择匹配的实体(位于两个表中)。您可以执行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

Group by看起来像这样:

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)
    {
        // ...
    }
}