Я хочу найти все элементы в одной коллекции, которые не соответствуют другой коллекции. Однако коллекции не одного типа; Я хочу написать выражение лямбда для указания равенства.
A LINQPad пример того, что я пытаюсь сделать:
void Main()
{
var employees = new[]
{
new Employee { Id = 20, Name = "Bob" },
new Employee { Id = 10, Name = "Bill" },
new Employee { Id = 30, Name = "Frank" }
};
var managers = new[]
{
new Manager { EmployeeId = 20 },
new Manager { EmployeeId = 30 }
};
var nonManagers =
from employee in employees
where !(managers.Any(x => x.EmployeeId == employee.Id))
select employee;
nonManagers.Dump();
// Based on cdonner answer:
var nonManagers2 =
from employee in employees
join manager in managers
on employee.Id equals manager.EmployeeId
into tempManagers
from manager in tempManagers.DefaultIfEmpty()
where manager == null
select employee;
nonManagers2.Dump();
// Based on Richard Hein answer:
var nonManagers3 =
employees.Except(
from employee in employees
join manager in managers
on employee.Id equals manager.EmployeeId
select employee);
nonManagers3.Dump();
}
public class Employee
{
public int Id { get; set; }
public string Name { get; set; }
}
public class Manager
{
public int EmployeeId { get; set; }
}
Вышеупомянутые работы и будут возвращены Билл сотрудника (№ 10). Однако это не кажется элегантным, и это может быть неэффективно с большими коллекциями. В SQL я бы, вероятно, сделал LEFT JOIN и нашел элементы, где второй идентификатор был NULL. Какая наилучшая практика для этого в LINQ?
EDIT: Обновлено для предотвращения решений, которые зависят от Id, равного индексу.
EDIT: добавлено решение cdonner - у кого-нибудь проще?
EDIT: Добавлен вариант ответа Ричарда Хейна, моего нынешнего фаворита. Спасибо всем за отличные ответы!