使用 LINQ 查询加入两个列表

Join two list using LINQ query

我正在尝试加入两个列表并对它们执行 LINQ 查询以显示这两个列表中的白色和黑色汽车,到目前为止代码完成了工作,但这不是我真正想要的结果,这是我的代码:

static void Main()
{
    List<Cars> cars = new List<Cars>
    {
        new Cars { Make = "Honda", Model = 2000, Color = "Black" },
        new Cars { Make = "Suzuki", Model = 1999, Color = "White" },
        new Cars { Make = "Toyota", Model = 2020, Color = "Green" },
        new Cars { Make = "Kia", Model = 2020, Color = "Blue" }
    };
     List<MakeBy> makeby = new List<MakeBy>
        {
            new MakeBy { Make = "Tesla", Model = 1998, Color = "Black" },
            new MakeBy { Make = "Audi", Model = 2015, Color = "White" },
            new MakeBy { Make = "Mercedes", Model = 2021, Color = "Green" },
            new MakeBy { Make = "Ford", Model = 1991, Color = "Blue" }
        };
    var CombineCars = cars.Join(makeby,
                        c => c.Color,
                        m => m.Colour,
                        (c, m) => new
                        {
                            carMake = c.Make,
                            carModel = c.Model,
                            carColor = c.Color,
                            makeByColor = m.Colour,
                            makeByCountry = m.Country
                        });
    foreach (var car in CombineCars)
    {
        Console.WriteLine($"Car model: {car.carModel}, car make: {car.carMake}, Car Color: {car.carColor}, Make By: {car.makeByCountry}, Make Color is: {car.makeByColor}"); 
    }
    Console.ReadLine();
}

显示此结果的这段代码:

Car model: 2000, car make: Honda, Car Color: Black, Make By: Japan, Make Color is: Black
Car model: 1999, car make: Suzuki, Car Color: White, Make By: China, Make Color is: White
Car model: 1999, car make: Suzuki, Car Color: White, Make By: Japan, Make Color is: White
Car model: 1999, car make: Suzuki, Car Color: White, Make By: Korea, Make Color is: White

第一个列表中只有一辆白色汽车,为什么加入这两个列表后我的代码显示多了2辆白色汽车?请告诉我加入后是否有改进的方式来显示这些列表。

这是预期的行为。 Join 将查找第二个列表中具有相同值的所有记录,并过滤掉右侧没有值的记录。

根据资料,这里不能用Join,但是Zip


var CombineCars = cars.Zip(makeby,
    (c, m) => new
    {
        carMake = c.Make,
        carModel = c.Model,
        carColor = c.Color,
        makeByColor = m.Colour,
        makeByCountry = m.Country
    });

如果您想保留 cars 集合中的项目列表,那么您可以使用 Select 方法和 Where 来按 Color 属性 进行过滤:

var filtered = cars
   .Where(w => w.Color == "Black" || w.Color == "White")
   .Select(s => new
   {
       s.Make,
       s.Model,
       s.Color,
       MakeByColor = makeby.FirstOrDefault(f => f.Colour == s.Color)?.Colour,
       MakeByCountry = makeby.FirstOrDefault(f => f.Colour == s.Color)?.Country
   });

更新:

您可以使用 Union 方法合并不相关的项目:

var uniqueMakeby = makeby.Select(s => s.Colour).Distinct();            
var selectedCars = cars
    .Where(w => uniqueMakeby.Contains(w.Color))
    .Select(s => new
    {
        s.Make,
        s.Model,
        s.Color,
        Country = string.Empty
    });
var unioned = selectedCars.Union(
    from x in makeby select new 
    { 
        Make = string.Empty, 
        Model = 0, 
        Color = x.Colour, 
        x.Country
     }
);

如果我没有正确理解你的问题,你只是想过滤加入的列表,如果是这种情况,那么这可能有效:

var combinedCars = from c in cars
               where c.Color == "White" || c.Color == "Black"
               join m in makeby on c.Color equals m.Color
               select new
               {
                   carMake = c.Make,
                   carModel = c.Model,
                   carColor = c.Color,
                   makeByColor = m.Color,
                   makeByModel = m.Model,
                   makeByMake = m.Make
               };

礼貌:Richard Deeming