Nota
O acesso a esta página requer autorização. Pode tentar iniciar sessão ou alterar os diretórios.
O acesso a esta página requer autorização. Pode tentar alterar os diretórios.
As operações de conjunto no LINQ referem-se a operações de consulta que produzem um conjunto de resultados com base na presença ou ausência de elementos equivalentes dentro das mesmas coleções ou coleções separadas.
Importante
Esses exemplos usam uma fonte de System.Collections.Generic.IEnumerable<T> dados. Fontes de dados baseadas em System.Linq.IQueryProvider uso de fontes de dados System.Linq.IQueryable<T> e árvores de expressão. As árvores de expressão têm limitações na sintaxe C# permitida. Além disso, cada IQueryProvider fonte de dados, como o EF Core , pode impor mais restrições. Verifique a documentação da sua fonte de dados.
| Nomes de método | Descrição | Sintaxe da expressão de consulta C# | Mais informações |
|---|---|---|---|
Distinct ou DistinctBy |
Remove valores duplicados de uma coleção. | Não aplicável. | Enumerable.Distinct Enumerable.DistinctBy Queryable.Distinct Queryable.DistinctBy |
Except ou ExceptBy |
Retorna a diferença definida, o que significa os elementos de uma coleção que não aparecem em uma segunda coleção. | Não aplicável. | Enumerable.Except Enumerable.ExceptBy Queryable.Except Queryable.ExceptBy |
Intersect ou IntersectBy |
Retorna a interseção do conjunto, o que significa elementos que aparecem em cada uma das duas coleções. | Não aplicável. | Enumerable.Intersect Enumerable.IntersectBy Queryable.Intersect Queryable.IntersectBy |
Union ou UnionBy |
Retorna a união do conjunto, o que significa elementos exclusivos que aparecem em qualquer uma das duas coleções. | Não aplicável. | Enumerable.Union Enumerable.UnionBy Queryable.Union Queryable.UnionBy |
Distinct e DistinctBy
O exemplo a seguir descreve o comportamento do método Enumerable.Distinct em uma sequência de strings. A sequência retornada contém os elementos exclusivos da sequência de entrada.
string[] words = ["the", "quick", "brown", "fox", "jumped", "over", "the", "lazy", "dog"];
IEnumerable<string> query = from word in words.Distinct()
select word;
foreach (var str in query)
{
Console.WriteLine(str);
}
/* This code produces the following output:
*
* the
* quick
* brown
* fox
* jumped
* over
* lazy
* dog
*/
Uma abordagem alternativa ao Distinct que requer um keySelector. O keySelector é usado como o discriminador comparativo do tipo de fonte. No código a seguir, as palavras são discriminadas com base em seu Length, e a primeira palavra de cada comprimento é exibida:
string[] words = ["the", "quick", "brown", "fox", "jumped", "over", "the", "lazy", "dog"];
foreach (string word in words.DistinctBy(p => p.Length))
{
Console.WriteLine(word);
}
// This code produces the following output:
// the
// quick
// jumped
// over
Except e ExceptBy
O exemplo a seguir descreve o comportamento de Enumerable.Except. A sequência retornada contém apenas os elementos da primeira sequência de entrada que não estão na segunda sequência de entrada.
Nota
Os exemplos a seguir neste artigo usam as fontes de dados comuns para essa área.
Cada Student tem um nível de grau, um departamento principal e uma série de classificações. A Teacher também tem uma City propriedade que identifica o campus onde o professor tem aulas. A Department tem um nome, e uma referência a um Teacher que serve como chefe de departamento.
Você pode encontrar o conjunto de dados de exemplo no repositório de origem.
public enum GradeLevel
{
FirstYear = 1,
SecondYear,
ThirdYear,
FourthYear
};
public class Student
{
public required string FirstName { get; init; }
public required string LastName { get; init; }
public required int ID { get; init; }
public required GradeLevel Year { get; init; }
public required List<int> Scores { get; init; }
public required int DepartmentID { get; init; }
}
public class Teacher
{
public required string First { get; init; }
public required string Last { get; init; }
public required int ID { get; init; }
public required string City { get; init; }
}
public class Department
{
public required string Name { get; init; }
public int ID { get; init; }
public required int TeacherID { get; init; }
}
Nota
Você pode consultar as fontes de dados comuns para essa área no artigo Visão geral dos operadores de consulta padrão .
string[] words1 = ["the", "quick", "brown", "fox"];
string[] words2 = ["jumped", "over", "the", "lazy", "dog"];
IEnumerable<string> query = from word in words1.Except(words2)
select word;
foreach (var str in query)
{
Console.WriteLine(str);
}
/* This code produces the following output:
*
* quick
* brown
* fox
*/
O ExceptBy método é uma abordagem alternativa para Except que toma duas sequências de tipos possivelmente heterogéneos e um keySelector. O tipo do keySelector é igual ao tipo da primeira coleção. Considere a seguinte Teacher matriz e os IDs de professores a excluir. Para encontrar professores na primeira coleção que não estejam na segunda coleção, você pode projetar o ID do professor na segunda coleção:
int[] teachersToExclude =
[
901, // English
965, // Mathematics
932, // Engineering
945, // Economics
987, // Physics
901 // Chemistry
];
foreach (Teacher teacher in
teachers.ExceptBy(
teachersToExclude, teacher => teacher.ID))
{
Console.WriteLine($"{teacher.First} {teacher.Last}");
}
No código C# anterior:
- A
teachersmatriz é filtrada apenas para os professores que não estão nateachersToExcludematriz. - A
teachersToExcludematriz contém oIDvalor para todos os chefes de departamento. - A chamada para
ExceptByresulta em um novo conjunto de valores que são gravados no console.
O novo conjunto de valores é do tipo Teacher, que é o tipo da primeira coleção. Cada teacher na matriz teachers que não tiver um valor de ID correspondente na matriz teachersToExclude é escrito no console.
Intersect e IntersectBy
O exemplo a seguir descreve o comportamento de Enumerable.Intersect. A sequência retornada contém os elementos que são comuns a ambas as sequências de entrada.
string[] words1 = ["the", "quick", "brown", "fox"];
string[] words2 = ["jumped", "over", "the", "lazy", "dog"];
IEnumerable<string> query = from word in words1.Intersect(words2)
select word;
foreach (var str in query)
{
Console.WriteLine(str);
}
/* This code produces the following output:
*
* the
*/
O IntersectBy método é uma abordagem alternativa para Intersect que toma duas sequências de tipos possivelmente heterogéneos e um keySelector. O keySelector é usado como o discriminador comparativo do tipo da segunda coleção. Considere as seguintes matrizes de alunos e professores. A consulta correlaciona os itens em cada sequência por nome para encontrar os alunos que também são professores:
foreach (Student person in
students.IntersectBy(
teachers.Select(t => (t.First, t.Last)), s => (s.FirstName, s.LastName)))
{
Console.WriteLine($"{person.FirstName} {person.LastName}");
}
No código C# anterior:
- A consulta produz a interseção do
Teachere doStudentcomparando os nomes. - Apenas as pessoas que são encontradas em ambas as matrizes estão presentes na sequência resultante.
- As instâncias resultantes
Studentsão gravadas na consola.
Union e UnionBy
O exemplo a seguir descreve uma operação de união em duas sequências de cadeias de caracteres. A sequência retornada contém os elementos exclusivos de ambas as sequências de entrada.
string[] words1 = ["the", "quick", "brown", "fox"];
string[] words2 = ["jumped", "over", "the", "lazy", "dog"];
IEnumerable<string> query = from word in words1.Union(words2)
select word;
foreach (var str in query)
{
Console.WriteLine(str);
}
/* This code produces the following output:
*
* the
* quick
* brown
* fox
* jumped
* over
* lazy
* dog
*/
O UnionBy método é uma abordagem alternativa para Union que toma duas sequências do mesmo tipo e um keySelector. O keySelector é usado como o discriminador comparativo do tipo de fonte. A consulta a seguir produz a lista de todas as pessoas que são alunos ou professores. Os alunos que também são professores são adicionados ao conjunto sindical apenas uma vez:
foreach (var person in
students.Select(s => (s.FirstName, s.LastName)).UnionBy(
teachers.Select(t => (FirstName: t.First, LastName: t.Last)), s => (s.FirstName, s.LastName)))
{
Console.WriteLine($"{person.FirstName} {person.LastName}");
}
No código C# anterior:
- As matrizes
teachersestudentssão tecidas juntas usando os seus nomes como o seletor de chave. - Os nomes resultantes são gravados no console.