使用 Linq 使用 DTO return 多个值

Use Linq to return multiple values using DTO

//This is student model
namespace StudentApp.Models
{
    public class Student
    {
        [Key]
        public int studentId { get; set; }
        public List<AssignedSupervisor> assigned_supervisorId { get; set; }
    }
    public class AssignedSupervisor
    {
        [Key]
        public int supervisorId { get; set; }
    }
}

基于学生模型,entity framework 创建了以下数据库

//Here is the sample db structure
//Table Students
studentId
---------
    1
    2
//Table Supervisors
supervisorId | studentId
------------   ---------
     101           1
     102           1
     105           2

studentId 是 Supervisor Table 中的外键。学生可以指定一名或多名导师。 所需的输出应类似于以下示例:

{
  "studentId": "1",
  "supervisorId": [101,102]
},
{
  "studentId": "2",
  "supervisorId": [105]
}

下面是DTO

//This is student DTO
namespace StudentApp.DTOs
{
    public class StudentDTO
    {
        public int studentId { get; set; }
        public List<AssignedSupervisor> assigned_supervisorId { get; set; }
    }
}

在我的控制器中

namespace ContractingApp.Controllers
{
    //first way I'm doing which returns ugly JSON.
    public List<StudentDTO> GetStudents()
    {
        return db.Students.Select(s => new StudentDTO()
        {
            studentId = s.studentId,
            //Not sure how to use the select statement with it
            assigned_supervisorId = s.Supervisors.Where(
                u => u.studentId == s.studentId
                ).ToList()
        }).ToList();
    }

    //Another way I have tried after the suggestions by @darth_phoenixx I'm trying which doesn't return correct correct format either.
    //It returns 3 JSON objects - one with each supervisor ID.
    public List<dynamic> GetStudents()
    {
        var students = (from t1 in db.Students
                        join t2 in db.Supervisors on t1.studentId equals t2.studentId
                        select new
                        {
                           t1.studentId,
                           t2.supervisorId
                        });
        return students.ToList<dynamic>();
    }
}

解决任何文章或方向都会有所帮助。

我在 Whosebug 上找到了提示。感谢@Aducci 回答关于 Mapping Linq Query results to a DTO class

的问题

问题出在我的 DTO 上。正确的 DTO 应该是:

//SupervisorId is in another DTO and has the correct data type as it is in the DB.
namespace StudentApp.DTOs
{
    public class StudentDTO
    {
        public int studentId { get; set; }
        public IEnumerable<SupervisorDTO> assigned_supervisorId { get; set; }
        //assigned_supervisorId in Student Model needs to be IEnumerable to work with this change in DTO.
    }
    //Separate DTO for supervisor
    public class SupervisorDTO
    {
        public int supervisorId { get; set; }
    }
}

对 DTO 进行排序后,Whosebug 的回答有助于完成 'chaining' 的查询。对于每个查询,都需要使用相关的 DTO。这是我的 WebAPI 中的最终控制器。 (db是Entity Framework的对象)

public IEnumerable<StudentDTO> GetStudents()
{
    return (from t1 in db.Students
            select new StudentDTO()
            {
                studentId = t1.StudentId,
                assigned_supervisorId = (from t2 in db.Supervisors
                                where t1.StudentId == t2.StudentId
                                select new SupervisorDTO() // Supervisor DTO needs to be used here
                                {
                                    supervisorId = t2.supervisorId
                                })
            });
}