【问题标题】:Take data from different tables and display it in View Index从不同的表中获取数据并在视图索引中显示
【发布时间】:2015-10-08 12:48:07
【问题描述】:

我有 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&lt;EmployeeViewModel&gt; 并将其作为模型传递给视图。正如我之前提到的,视图应该接收IEnumerable&lt;EmployeeViewModel&gt; 类型的模型,所以我需要查询我的实体,它应该是这样的:

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      |

如何删除重复项?

【问题讨论】:

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


    【解决方案1】:

    在数据库世界中,您在这里需要的是 LEFT JOIN。在 SQL 中连接两个表的方式有很多种。每个变体都提供不同的结果。默认的 JOIN 是一个 INNER 连接,这意味着结果集中的每个实体都存在于 both 表中。 LEFT 连接意味着实体可以存在于两个表中,但不能存在。如果第二个表中不存在,则返回空结果集。有两个表 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,因此只会选择匹配的实体(在两个表中)。你可以做一个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)
        {
            // ...
        }
    }
    

    【讨论】:

    • 谢谢大家,它有效。但是当我插入具有相同 EmployeeId 的 2 行时,它出现在employee1 job1 employee1 job2 下方,我只想加载employee1,我怎么能这样做,我认为它看起来很不同?请非常感谢您
    • employee1 be load 是什么意思?你在你的问题中说And I want to display both employees
    • 谢谢大家,显示两者都是工作。但是当我插入具有相同 EmployeeId 的 2 行时,它出现在employee1 job1 employee1 job2 下方,我只想加载employee1,我怎么能这样做,我认为它看起来很不同?请非常感谢您
    • 是的,使用Distinct extensionmodel.Distinct()。我已经修改了答案中的代码。
    • tnanks 为您的示例。我把 distinct() 但它不起作用 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 : "没有工作条目" }).distinct();我如何将 distinct() 放入?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2018-12-04
    • 1970-01-01
    • 2014-07-17
    • 2016-09-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多