我写了两个集合之间的分组联接
1名学生
2马德拉克
每个madrak有很多学生,每个学生都有一个madrak
换句话说,表之间存在一对多关系

分组加入的结果是
![群组加入]:(https://pasteboard.co/IibmzbL.jpg

重复两次。
我不明白为什么我们有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; }
}
}

最佳答案

我不明白为什么我们有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}
{}


一共有三所学校,因此您应该在小组参加活动中获得三排。

现在,为什么获得查询结果呢?您已将组加入重新变成常规加入。让我们尝试对您的查询进行变体:

         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{}


这一切有意义吗?

关于c# - 为什么分组连接的结果重复2次?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/56481954/

10-17 01:12