我假设有一个简单的LINQ查询来做到这一点,我只是不太确定如何。

给定这段代码:

class Program
{
    static void Main(string[] args)
    {
        List<Person> peopleList1 = new List<Person>();
        peopleList1.Add(new Person() { ID = 1 });
        peopleList1.Add(new Person() { ID = 2 });
        peopleList1.Add(new Person() { ID = 3 });

        List<Person> peopleList2 = new List<Person>();
        peopleList2.Add(new Person() { ID = 1 });
        peopleList2.Add(new Person() { ID = 2 });
        peopleList2.Add(new Person() { ID = 3 });
        peopleList2.Add(new Person() { ID = 4 });
        peopleList2.Add(new Person() { ID = 5 });
    }
}

class Person
{
    public int ID { get; set; }
}

我想执行一个LINQ查询,给我所有人在peopleList2不在peopleList1。

这个例子应该给我两个人(ID = 4 & ID = 5)


当前回答

Klaus的回答很好,但是ReSharper会让你“简化LINQ表达式”:

var result = peopleList2。Where(p => peopleList1.)p2 => p2。= p.ID));

其他回答

这个可枚举扩展允许您定义要排除的项的列表和用于查找用于执行比较的键的函数。

public static class EnumerableExtensions
{
    public static IEnumerable<TSource> Exclude<TSource, TKey>(this IEnumerable<TSource> source,
    IEnumerable<TSource> exclude, Func<TSource, TKey> keySelector)
    {
       var excludedSet = new HashSet<TKey>(exclude.Select(keySelector));
       return source.Where(item => !excludedSet.Contains(keySelector(item)));
    }
}

你可以这样使用它

list1.Exclude(list2, i => i.ID);

这可以用下面的LINQ表达式来解决:

var result = peopleList2.Where(p => !peopleList1.Any(p2 => p2.ID == p.ID));

通过LINQ表达的另一种方式,一些开发人员认为更易于阅读:

var result = peopleList2.Where(p => peopleList1.All(p2 => p2.ID != p.ID));

警告:正如评论中所指出的,这些方法要求O(n*m)操作。这可能没问题,但可能会带来性能问题,特别是在数据集相当大的情况下。如果这不能满足您的性能要求,您可能需要评估其他选项。但是,由于声明的需求是LINQ中的解决方案,所以这里不讨论这些选项。与往常一样,根据项目的性能需求评估任何方法。

下面是一个实际的例子,它能让你掌握求职者不具备的IT技能 已经有了。

//Get a list of skills from the Skill table
IEnumerable<Skill> skillenum = skillrepository.Skill;
//Get a list of skills the candidate has                   
IEnumerable<CandSkill> candskillenum = candskillrepository.CandSkill
       .Where(p => p.Candidate_ID == Candidate_ID);             
//Using the enum lists with LINQ filter out the skills not in the candidate skill list
IEnumerable<Skill> skillenumresult = skillenum.Where(p => !candskillenum.Any(p2 => p2.Skill_ID == p.Skill_ID));
//Assign the selectable list to a viewBag
ViewBag.SelSkills = new SelectList(skillenumresult, "Skill_ID", "Skill_Name", 1);

有点晚了,但一个很好的解决方案,也是Linq到SQL兼容的是:

List<string> list1 = new List<string>() { "1", "2", "3" };
List<string> list2 = new List<string>() { "2", "4" };

List<string> inList1ButNotList2 = (from o in list1
                                   join p in list2 on o equals p into t
                                   from od in t.DefaultIfEmpty()
                                   where od == null
                                   select o).ToList<string>();

List<string> inList2ButNotList1 = (from o in list2
                                   join p in list1 on o equals p into t
                                   from od in t.DefaultIfEmpty()
                                   where od == null
                                   select o).ToList<string>();

List<string> inBoth = (from o in list1
                       join p in list2 on o equals p into t
                       from od in t.DefaultIfEmpty()
                       where od != null
                       select od).ToList<string>();

向http://www.dotnet-tricks.com/Tutorial/linq/UXPF181012-SQL-Joins-with-C致敬

Klaus的回答很好,但是ReSharper会让你“简化LINQ表达式”:

var result = peopleList2。Where(p => peopleList1.)p2 => p2。= p.ID));