可以说我有以下表格:
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()
};
答案 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()
};