LINQ查询特定情况

时间:2019-01-17 18:58:06

标签: c# linq

可以说我有以下表格:

 Student(id(pk), name)
 Class(id(pk), name)
 StudentClass(id(pk), studentId(fk), classId(fk))

想象一下:

Student表包含:

 (1,"John"), (2, "Mike"), (3,"Josh")

Class表包含:

(1,"Geography"), (2, "Math")

StudentClass表包含:

(`1, 1, 1),(2,2,2),(3,3,2)

现在让我们假设我有一个StudentClassDTO类,其中包含

List<string> StudentNames
string ClassName

如何使用LINQ查询将数据获取到StudentClassDTO中?任何帮助表示赞赏。

    var data = from sc in context.GetStudentClasses
               join s in context.GetStudents on sc.StudentId equals s.Id
               join c in context.GetClass on sc.ClassId equals c.Id
               select new StudentClassDTO
               {

               }

因此它得到的名称和班级名是3个单独的班级,但我需要,如果他们的班级相同,则必须将它们组合在一起,这将是一个班级名和2个不同的学生。因此应该像{john,Geography}和{[Mike,Josh],Math}

解决方案

                   from c in classes
                   join sc in studentClasses on c.Id equals sc.ClassId
                   join s in student on sc.StudentId equals s.StudentId 
                   group s by new {c.Name} into g
                   select new StudentClassDTO
                   {
                       ClassName = g.Key.Name,
                       StudentNames = g.Select(a=>a.Name).ToList()
                   };

2 个答案:

答案 0 :(得分:0)

我一直使用这样的代码来完成您要尝试执行的操作(未经测试并使用C#7.3语法)。

var xs =
    from s in ctx.students 
        join cs in ctx.student_classes on cs.student_id equals s.student_id 
        join c in ctx.classes on c.class_id equals cs.class_id

    select new 
    {
        s, c
    }

var memo = new Dictionary<int, StudentClassDTO>(); //the key is class_id

foreach(var x in xs)
{
    if(!memo.Contains(x.c.class_id, out var @class))
        memo.Add(x.c.class_id, @class = new StudentClassDTO(x.c.class_name));

    @class.Accept(s.student_name);
}


sealed class StudentClassDTO
{
    readonly List<string> student_names;

    public string ClassName { get; }

    public IEnumerable<string> StudentNames => student_names;       

    public(string class_name)
    {
        ClassName = class_name;
    }

    public void Accept(string name) => student_names.Add(name);     
}

答案 1 :(得分:0)

使用LINQ组联接运算符,可以获取匹配的学生班级的集合,但是您需要从班级表开始查询,因为您希望每个班级一个StudentClassDTO。不幸的是,您必须将join从学生班级嵌套到学生(EF导航属性可能会更好),这样可能会生成多个查询。

var data = from c in context.GetClass
           join sc in context.GetStudentClasses on c.Id equals sc.ClassId into scj
           select new StudentClassDTO {
               ClassName = c.Name,
               StudentNames = (from sc in scj
                               join s in context.GetStudents on sc.StudentId equals s.Id
                               select s.Name).ToList()
           };