我在2个收藏夹之间编写了分组联接 1名学生 2马德拉克 每个madrak有很多学生,每个学生都有一个madrak 换句话说,表之间存在一对多的关系
分组加入的结果是 ![group join]:({https://pasteboard.co/IibmzbL.jpg)
重复2次。 我不明白为什么我们有4个小组
namespace ConsoleApp4{
class Program
{
static void Main(string[] args)
{
IList<Student> studentList = new List<Student>()
{
new Student() { StudentID = 1, StudentName
= "davod zarei", MadrakID =1 },
new Student() { StudentID = 2, StudentName
= "eshrat alipour", MadrakID =1 },
new Student() { StudentID = 3, StudentName
= "hadi pournader", MadrakID =2 },
new Student() { StudentID = 4, StudentName
= "mahdi chegini", MadrakID =2 },
new Student() { StudentID = 5, StudentName
= "Bozorg Mirzahoseini"}
};
IList<Madrak> madrakList = new List<Madrak>()
{
new Madrak(){ MadrakID = 1,
MadrakName="lisance"},
new Madrak(){ MadrakID = 2,
MadrakName="arshad"},
new Madrak(){ MadrakID = 3,
MadrakName="phd"},
};
var GroupJoinResult2 =
from md in madrakList
join stu in studentList
on md.MadrakID equals stu.MadrakID into MachedStudent
from item in MachedStudent
select new { Key = md.MadrakID, Items = MachedStudent };
Console.WriteLine("---------- group Join Result ----------");
foreach (var item in GroupJoinResult2)
{
Console.WriteLine(item.Key + ":");
foreach (var element in item.Items)
{
Console.WriteLine(" " + element.StudentName);
}
}
Console.ReadKey();
}
}
public class Student
{
public int StudentID { get; set; }
public string StudentName { get; set; }
public int MadrakID { get; set; }
}
public class Madrak
{
public int MadrakID { get; set; }
public string MadrakName { get; set; }
}
}
答案 0 :(得分:6)
我不明白为什么我们有4个小组
通过将一组学生与一个学生混淆,您将组加入和常规加入做了一个非常奇怪的组合。
让我们详细了解一下。
我将简化您的代码。让我们从简化学生类型开始:
public class Student
{
public Student(string s, string m)
{
StudentName = s;
MadrakName = m;
}
public string StudentName { get; set; }
public string MadrakName { get; set; }
public override string ToString() { return StudentName; }
}
学校可以只是一串绳子。所以现在我们有四个学生和三个学校:
var studentList = new List<Student>() {
new Student("S1", "M1"),
new Student("S2", "M1"),
new Student("S3", "M2"),
new Student("S4", "M2")
};
var madrakList = new List<string>() { "M1", "M2", "M3" };
第三所学校没有学生。
我们想要什么?我们想要每个学校的学生名单。就是说,我们应该得到三个清单。第一个列表应该是S1和S2,第二个应该是S3和S4,第三个应该为空:
var q =
from m in madrakList
join s in studentList
on m equals s.MadrakName into MatchedStudent
select MatchedStudent;
现在让我们打印出每个:
foreach(var item in q)
Console.WriteLine("{" + string.Join(",", item) + "}");
我们得到了想要的东西:
{S1,S2}
{S3,S4}
{}
有3所学校,所以您的小组参加活动应该有3行。
现在,为什么要获得查询所得到的结果? 您已将群组加入重新设置为常规加入。让我们尝试对您的查询进行修改:
from m in madrakList
join s in studentList
on m equals s.MadrakName into MatchedStudent
from item in MatchedStudent
select new { Key = m, Items = item };
item
取值S1,S2,S3,S4,这表示创建一个元组,其中键是学校,m
,项是学生。您所做的只是一种非常复杂的书写方式
from m in madrakList
join s in studentList
on m equals s.MadrakName
select new { Key = m, Items = s }
即普通联接,而不是组联接。显然有四行,因为它们是:
M1, S1
M1, S2
M2, S3
M2, S4
有四名学生在上学,所以您的普通加入应有四行。
但这不是您写的。你写了
from m in madrakList
join s in studentList
on m equals s.MadrakName into MatchedStudent
from item in MatchedStudent
select new { Key = m, Items = MatchedStudent };
// MatchedStudent is a list of students!
那么,你现在得到了什么?代替
M1, S1
M1, S2
M2, S3
M2, S4
在该列中有一个学生的地方,相反,在该列中有所有匹配的学生:
M1, {S1, S2} // From S1
M1, {S1, S2} // From S2
M2, {S3, S4} // From S3
M2, {S3, S4} // From S4
基本上,您已经编写了一个非常奇怪的组合,包括常规联接和组联接。该表格采用常规联接的形式,分为四行,每行一所学校,每个学生一个,但是该行中的每个“学生”都是该组中匹配的学生的整个列表。 >
您似乎很困惑,并且忘记了MatchedStudent
是学生的列表,因为它是组加入。您像对待学生一样对待它,但这也是错误的。
可能您打算编写的代码是:
var q =
from m in madrakList
join s in studentList
on m equals s.MadrakName into studentsInMadrak
select new { Madrak = m, Students = studentsInMadrak };
foreach(var item in q)
Console.WriteLine(item.Madrak + "{" +
string.Join(",", item.Students) + "}");
哪个打印出来
M1{S1,S2}
M2{S3,S4}
M3{}
这一切有意义吗?