Eu diria que há uma consulta LINQ simples para fazer isso, mas não sei exatamente como.
Dado este pedaço de código:
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; }
}
Gostaria de executar uma consulta LINQ para me fornecer todas as pessoas peopleList2
que não estão peopleList1
.
Este exemplo deve me dar duas pessoas (ID = 4 e ID = 5)
Respostas:
Isso pode ser resolvido usando a seguinte expressão LINQ:
Uma maneira alternativa de expressar isso via LINQ, que alguns desenvolvedores acham mais legível:
fonte
Se você substituir a igualdade de Pessoas, também poderá usar:
Except
deve ser significativamente mais rápido que aWhere(...Any)
variante, pois pode colocar a segunda lista em uma hashtable.Where(...Any)
tem um tempo de execução deO(peopleList1.Count * peopleList2.Count)
enquanto as variantes baseadas emHashSet<T>
(quase) têm um tempo de execução deO(peopleList1.Count + peopleList2.Count)
.Except
remove implicitamente duplicatas. Isso não deve afetar o seu caso, mas pode ser um problema para casos semelhantes.Ou se você deseja um código rápido, mas não deseja substituir a igualdade:
Esta variante não remove duplicatas.
fonte
Equals
tivesse sido substituído para comparar IDs.Ou se você quiser sem negação:
Basicamente, ele diz que obtém tudo do peopleList2, onde todos os IDs do peopleList1 são diferentes do id do PeopleList2.
Abordagem apenas um pouco diferente da resposta aceita :)
fonte
Como todas as soluções até o momento usavam sintaxe fluente, eis uma solução na sintaxe da expressão de consulta, para os interessados:
Eu acho que é diferente o suficiente das respostas dadas para interessar a alguns, mesmo pensando que provavelmente seria subótimo para Listas. Agora, para tabelas com IDs indexados, esse seria definitivamente o caminho.
fonte
Tarde demais para a festa, mas uma boa solução que também é compatível com Linq to SQL é:
Parabéns pelo http://www.dotnet-tricks.com/Tutorial/linq/UXPF181012-SQL-Joins-with-C
fonte
A resposta de Klaus foi ótima, mas o ReSharper solicitará que você "Simplifique a expressão LINQ":
var result = peopleList2.Where(p => peopleList1.All(p2 => p2.ID != p.ID));
fonte
Esta extensão enumerável permite que você defina uma lista de itens a serem excluídos e uma função a ser usada para encontrar a chave a ser usada na comparação.
Você pode usá-lo desta maneira
fonte
Aqui está um exemplo de trabalho que obtém habilidades de TI que um candidato a emprego ainda não possui.
fonte
primeiro, extraia os IDs da coleção em que a condição
segundo, use o parâmetro "compare" para selecionar os IDs diferentes da seleção
Obviamente, você pode usar x.key! = "TEST", mas é apenas um exemplo
fonte
Depois de escrever um FuncEqualityComparer genérico, você pode usá-lo em qualquer lugar.
fonte