简体   繁体   中英

Linq Left join, left collection items repeating in the results

I am trying to do a left join between two collections. In the results shown in the image, I was expecting to see Anand only once. What am I doing wrong

using System;
using System.Collections.Generic;
using System.Linq;

namespace LinqJoin
{
    internal class MainClass
    {
        public static void Main(string[] args)
        {
            var chessPlayers = new List<ChessPlayer>
                {
                    new ChessPlayer {FirstName = "Anand", Age = 51},
                    new ChessPlayer {FirstName = "Bobby", Age = 77},
                    new ChessPlayer {FirstName = "Kasprov", Age = 64}
                };

            var compScientists = new List<ComputerScientist>
                {
                    new ComputerScientist {FirstName = "Anand", Language = "C++"},
                    new ComputerScientist {FirstName = "Anand", Language = "C#"},
                    new ComputerScientist {FirstName = "Bobby", Language = "Java"},
                    new ComputerScientist {FirstName = "Steve", Language = "Ruby"},
                };


            var leftJoin =
                from ch in chessPlayers
                join cs in compScientists on ch.FirstName equals cs.FirstName
                    into chcs
                from cs in chcs.DefaultIfEmpty()
                select new {chessPlayer = ch, comp = chcs};

            foreach (var left in leftJoin)
            {
                Console.WriteLine("*********************");
                Console.WriteLine("{0} {1} ", left.chessPlayer.FirstName, left.chessPlayer.Age);
                foreach (ComputerScientist right in left.comp)
                {
                    Console.WriteLine("\t" + right.Language);
                }
            }
        }
    }


    internal class ChessPlayer
    {
        public string FirstName { get; set; }
        public int Age { get; set; }
    }

    internal class ComputerScientist
    {
        public string FirstName { get; set; }
        public string Language { get; set; }
    }
}

在此输入图像描述

You did nothing wrong, a left join will return back multiple rows if the join condition matches for each of the rows in question.

The best way to think of a left join is simply an inner join with non-matching rows returned with null values on the right table.

What I think you want out of that is the distinct list. In this case, you'll want to change

 foreach (var left in leftJoin)

to

foreach (var left in leftJoin.Distinct())

You clearly want GroupJoin instead of LeftJoin.

var query =
  from ch in chessPlayers
  join cs in compScientists on ch.FirstName equals cs.FirstName
    into g
  select new {chessPlayer = ch, comp = g.ToList()};

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM