繁体   English   中英

在LINQ中使用外部联接

[英]Using an outer join with LINQ

我有两个清单。 我的列表如下所示:

可用香料

ID  Name
--  ----
1   Vanilla
2   Chocolate
3   Strawberry
4   Rocky Road
5   Cookies and Cream

最喜欢的

ID  Name
--  ----
1   Vanilla
3   Strawberry

如何获得使用LINQ不在FavoriteFlavors列表中的AvailableFlavors列表? 目前我有:

List<Flavor> AvailableFlavors = GetAvailableFlavors();
List<Flavor> FavoriteFlavors = GetFavoriteFlavors();

AvailableFlavors = from availableFlavor in AvailableFlavors
                   // what goes here?
                   select availableFlavor;

使用您的自定义类Flavor我覆盖了Equals()ToString()并执行以下操作:

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

public class Program
{
    public static void Main()
    {
        List<Flavor> availableFlavors = new List<Flavor> () {
            new Flavor() { ID = 1, Name = "Vanilla" },
            new Flavor() { ID = 2, Name = "Chocolate" },
            new Flavor() { ID = 3, Name = "Strawberry" },
            new Flavor() { ID = 4, Name = "Rocky Road" },
            new Flavor() { ID = 5, Name = "Cookies and Cream"}
        };

        List<Flavor> favoriteFlavors = new List<Flavor>() {
            new Flavor() { ID = 1, Name = "Vanilla" },
            new Flavor() { ID = 3, Name = "Strawberry" },
        };

        availableFlavors.Where(f => !favoriteFlavors.Contains(f))
            .ToList()
            .ForEach(f => Console.WriteLine(f));
    }
}

public class Flavor
{
    public int ID { get; set; }
    public string Name { get; set; }

    public override bool Equals(object obj)
    {
        Flavor objToCheck = obj as Flavor;
        if (objToCheck != null)
        {
            if (objToCheck.ID == ID &&
                objToCheck.Name == Name)
            {
                return true;
            }
            return false;
        }
        return false;
    }

    public override string ToString()
    {
        return String.Format("ID: {0} Name: {1}", ID, Name);
    }
}

结果:

ID: 2 Name: Chocolate
ID: 4 Name: Rocky Road
ID: 5 Name: Cookies and Cream

演示版

// Select Name from favorite flavors
var favoriteFlavorNames = from favoriteFlavor in GetFavoriteFlavors()
                          select favoriteFlavor.Name;

// Find available flavors not in favorite flavors
var filteredAvailbleFlavors = from availableFlavor in GetAvailableFlavors()
                              where !favoriteFlavorNames.Contains(availableFlavor.Name)
                              select availableFlavor;

或者,您可以将两者合并为:

var filteredAvailbleFlavors = from availableFlavor in GetAvailableFlavors()
                              let favoriteFlavorNames = 
                                  (from favoriteFlavor in GetFavoriteFlavors()
                                   select favoriteFlavor.Name)
                              where !favoriteFlavorNames.Contains(availableFlavor.Name)
                              select availableFlavor;

简单的LINQ .Except调用可以解决问题:

List<Flavor> AvailableFlavors = GetAvailableFlavors();
List<Flavor> FavoriteFlavors = GetFavoriteFlavors();
var availableButNotFavoriteFlavors = AvailableFloavors.Except(FavoriteFlaovors);

结果是IEnumerable<Flavor> ,因此您可能需要转换回List。

编辑 :我猜的真正问题是如何编写自定义IEqualityComparer ,我们在`.Ex​​cept'方法中使用。 .Except文档页面有一个编写简单比较器的好例子。

如果您不愿意这样做,则可以使用.Where并手动比较属性:

var availableButNotFavoriteFlavors =
    AvailableFloavors
        .Where(af => !FavoriteFlavors.Any(ff => af.Id == ff.ID && af.Name == ff.Name);
AvailableFlavors.Where(af => !FavoriteFlavors.Any(ff => af.Name == ff.Name));

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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