Eu tenho duas coleções que possuem propriedades Email
em ambas as coleções. Preciso obter uma lista dos itens na primeira lista onde Email
não existe na segunda lista. Com o SQL, eu usaria "not in", mas não sei o equivalente no LINQ. Como isso é feito?
Até agora eu tenho uma junção, como ...
var matches = from item1 in list1
join item2 in list2 on item1.Email equals item2.Email
select new { Email = list1.Email };
Mas não posso participar, pois preciso da diferença e a associação falharia. Eu preciso de alguma maneira de usar Contém ou Existe, acredito. Eu apenas não encontrei um exemplo para fazer isso ainda.
Respostas:
Eu não sei se isso irá ajudá-lo, mas ..
da cláusula NOT IN no LINQ to SQL por Marco Russo
fonte
Você deseja o operador Exceto.
Melhor explicação aqui: https://docs.microsoft.com/archive/blogs/charlie/linq-farm-more-on-set-operators
NOTA: Essa técnica funciona melhor apenas para tipos primitivos, pois você precisa implementar um IEqualityComparer para usar o
Except
método com tipos complexos.fonte
list1.Select(item => new { Property1 = item.Property1, Property2 = item.Property2 }).Except(list2.Select( item => new { Property1 = item.Property1, Property2 = item.Property2 }));
isso é particularmente útil quando você determina a igualdade, avaliando apenas um conjunto de valores do tipo complexo.IEquatityComparor<T,T>
ou substituir métodos de comparação de objetos em umLinqToSql
cenário; pois, a consulta será representada como / compilada para / expressa como SQL; portanto, os valores serão verificados, não a referência do objeto.except
que eu era capaz de acelerar uma consulta LINQ de 8-10 segundos a um meio segundoPara pessoas que começam com um grupo de objetos na memória e estão consultando um banco de dados, descobri que esse é o melhor caminho a seguir:
Isso produz uma boa
WHERE ... IN (...)
cláusula no SQL.fonte
fonte
Você pode usar uma combinação de Onde e Qualquer para encontrar não em:
fonte
Você pode pegar as duas coleções em duas listas diferentes, como list1 e list2.
Então é só escrever
Isso vai funcionar.
fonte
No caso de alguém estar usando o ADO.NET Entity Framework , a solução da EchoStorm também funciona perfeitamente. Mas levei alguns minutos para envolver minha cabeça. Supondo que você tenha um contexto de banco de dados, dc e deseje encontrar linhas na tabela x não vinculadas na tabela y, a resposta completa da resposta será semelhante a:
Em resposta ao comentário de Andy, sim, é possível ter dois de em uma consulta LINQ. Aqui está um exemplo de trabalho completo, usando listas. Cada classe, Foo e Bar, tem um ID. Foo tem uma referência de "chave estrangeira" a Bar via Foo.BarId. O programa seleciona todos os Foo não vinculados a uma barra correspondente.
fonte
fonte
Pode-se também usar
All()
fonte
Embora faça
Except
parte da resposta, não é a resposta completa. Por padrão,Except
(como vários operadores LINQ), faz uma comparação de referência nos tipos de referência. Para comparar por valores nos objetos, você precisaráIEquatable<T>
em seu tipo ouEquals
eGetHashCode
no seu tipo ouIEqualityComparer<T>
para o seu tipofonte
Exemplo usando Lista de int por simplicidade.
fonte
Para quem também deseja usar um
IN
operador semelhante ao SQL em C #, baixe este pacote:Possui
In
eNotIn
métodos:Até você pode usá-lo dessa maneira
fonte
Obrigado, Brett. Sua sugestão também me ajudou. Eu tinha uma lista de objetos e queria filtrar isso usando outra lista de objetos. Obrigado novamente....
Se alguém precisar, dê uma olhada no meu exemplo de código:
fonte
Não testei isso com o LINQ to Entities :
Alternativamente:
fonte
Não foi possível fazer uma associação externa, apenas selecionando os itens da primeira lista se o grupo estiver vazio? Algo como:
Não tenho certeza se isso funcionaria de alguma forma eficiente com a estrutura da Entidade.
fonte
Como alternativa, você pode fazer assim:
fonte