Я бы предположил, что есть простой запрос 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)
Ответы:
Это можно решить с помощью следующего выражения LINQ:
Альтернативный способ выразить это через LINQ, который некоторые разработчики находят более читабельным:
источник
Если вы переопределите равенство людей, то вы также можете использовать:
Except
должен быть значительно быстрее, чемWhere(...Any)
вариант, поскольку он может поместить второй список в хеш-таблицу.Where(...Any)
имеет время выполнения,O(peopleList1.Count * peopleList2.Count)
тогда как варианты, основанныеHashSet<T>
(почти), имеют время выполненияO(peopleList1.Count + peopleList2.Count)
.Except
неявно удаляет дубликаты. Это не должно повлиять на ваш случай, но может быть проблемой для подобных случаев.Или, если вы хотите быстрый код, но не хотите переопределять равенство:
Этот вариант не удаляет дубликаты.
источник
Equals
бы было отменено сравнение идентификаторов.Или если хотите без отрицания
В основном это говорит получить все из peopleList2, где все идентификаторы в peopleList1 отличаются от идентификатора в peopleList2.
Просто немного отличается подход от принятого ответа :)
источник
Поскольку во всех решениях на сегодняшний день используется свободный синтаксис, вот решение для синтаксиса выражений запросов для интересующихся:
Я думаю, что он достаточно отличается от ответов, которые могут быть интересны для некоторых, даже если бы он был неоптимальным для списков. Теперь для таблиц с индексированными идентификаторами, это определенно будет путь.
источник
Немного опоздал на вечеринку, но хорошее решение, которое также совместимо с Linq to SQL:
Слава http://www.dotnet-tricks.com/Tutorial/linq/UXPF181012-SQL-Joins-with-C
источник
Клаус ответил великолепно, но ReSharper попросит вас «упростить выражение LINQ»:
var result = peopleList2.Where(p => peopleList1.All(p2 => p2.ID != p.ID));
источник
Это Enumerable Extension позволяет вам определить список исключаемых элементов и функцию, используемую для поиска ключа, который будет использоваться для сравнения.
Вы можете использовать это таким образом
источник
Вот рабочий пример, который дает ИТ-навыки, которых у кандидата на работу еще нет.
источник
во-первых, извлечь идентификаторы из коллекции, где условие
во-вторых, используйте положение «сравнить», чтобы выбрать идентификаторы, различающиеся для выбора
Очевидно, что вы можете использовать x.key! = "TEST", но это только пример
источник
Как только вы напишите общий FuncEqualityComparer, вы сможете использовать его везде.
источник