Noções básicas sobre expressões de consultaQuery expression basics

O que é uma consulta e o que ela faz?What is a query and what does it do?

Uma consulta é um conjunto de instruções que descreve quais dados recuperar de uma determinada fonte de dados (ou fontes) e que forma e organização os dados retornados devem ter.A query is a set of instructions that describes what data to retrieve from a given data source (or sources) and what shape and organization the returned data should have. Uma consulta é diferente dos resultados que ela produz.A query is distinct from the results that it produces.

Em geral, os dados de origem são organizados de forma lógica como uma sequência de elementos do mesmo tipo.Generally, the source data is organized logically as a sequence of elements of the same kind. Por exemplo, uma tabela de banco de dados SQL contém uma sequência de linhas.For example, a SQL database table contains a sequence of rows. Em um arquivo XML, há uma "sequência" de elementos XML (embora eles estejam organizados hierarquicamente em uma estrutura de árvore).In an XML file, there is a "sequence" of XML elements (although these are organized hierarchically in a tree structure). Uma coleção na memória contém uma sequência de objetos.An in-memory collection contains a sequence of objects.

Do ponto de vista do aplicativo, o tipo específico e a estrutura dos dados de origem original não são importantes.From an application's viewpoint, the specific type and structure of the original source data is not important. O aplicativo sempre vê os dados de origem como uma coleção de IEnumerable<T> ou de IQueryable<T>.The application always sees the source data as an IEnumerable<T> or IQueryable<T> collection. Por exemplo, no LINQ to XML, os dados de origem ficam visíveis como um IEnumerable<XElement>.For example, in LINQ to XML, the source data is made visible as an IEnumerable<XElement>.

Dada essa sequência de origem, uma consulta pode executar uma das três ações:Given this source sequence, a query may do one of three things:

  • Recuperar um subconjunto dos elementos para produzir uma nova sequência sem modificar os elementos individuais.Retrieve a subset of the elements to produce a new sequence without modifying the individual elements. A consulta pode, em seguida, classificar ou agrupar a sequência retornada de várias maneiras, conforme mostrado no exemplo a seguir (suponha que scores é um int[]):The query may then sort or group the returned sequence in various ways, as shown in the following example (assume scores is an int[]):

    IEnumerable<int> highScoresQuery =
        from score in scores
        where score > 80
        orderby score descending
        select score;
    
  • Recuperar uma sequência de elementos, como no exemplo anterior, mas transformá-los em um novo tipo de objeto.Retrieve a sequence of elements as in the previous example but transform them to a new type of object. Por exemplo, uma consulta pode recuperar apenas os sobrenomes de determinados registros de cliente em uma fonte de dados.For example, a query may retrieve only the last names from certain customer records in a data source. Ou pode recuperar o registro completo e, em seguida, usá-lo para construir outro tipo de objeto na memória ou até mesmo dados XML antes de gerar a sequência de resultados final.Or it may retrieve the complete record and then use it to construct another in-memory object type or even XML data before generating the final result sequence. O exemplo a seguir mostra uma projeção de um int para um string.The following example shows a projection from an int to a string. Observe o novo tipo de highScoresQuery.Note the new type of highScoresQuery.

    IEnumerable<string> highScoresQuery2 =
        from score in scores
        where score > 80
        orderby score descending
        select String.Format("The score is {0}", score);
    
  • Recuperar um valor singleton sobre os dados de origem, como:Retrieve a singleton value about the source data, such as:

    • O número de elementos que correspondem a uma determinada condição.The number of elements that match a certain condition.

    • O elemento que tem o maior ou menor valor.The element that has the greatest or least value.

    • O primeiro elemento que corresponde a uma condição ou a soma dos valores específicos em um conjunto de elementos especificado.The first element that matches a condition, or the sum of particular values in a specified set of elements. Por exemplo, a consulta a seguir retorna o número pontuações maiores que 80 na matriz de inteiros scores:For example, the following query returns the number of scores greater than 80 from the scores integer array:

    int highScoreCount =
        (from score in scores
         where score > 80
         select score)
         .Count();
    

    No exemplo anterior, observe o uso de parênteses ao redor da expressão de consulta antes da chamada para o método Count.In the previous example, note the use of parentheses around the query expression before the call to the Count method. Também é possível expressar isso usando uma nova variável para armazenar o resultado concreto.You can also express this by using a new variable to store the concrete result. Essa técnica é mais legível porque mantém a variável que armazena a consulta separada da consulta que armazena um resultado.This technique is more readable because it keeps the variable that stores the query separate from the query that stores a result.

    IEnumerable<int> highScoresQuery3 =
        from score in scores
        where score > 80
        select score;
    
    int scoreCount = highScoresQuery3.Count();
    

No exemplo anterior, a consulta é executada na chamada para Count, pois Count deve iterar os resultados para determinar o número de elementos retornados por highScoresQuery.In the previous example, the query is executed in the call to Count, because Count must iterate over the results in order to determine the number of elements returned by highScoresQuery.

O que é uma expressão de consulta?What is a query expression?

Uma expressão de consulta é uma consulta expressada na sintaxe da consulta.A query expression is a query expressed in query syntax. Uma expressão de consulta é um constructo de linguagem de primeira classe.A query expression is a first-class language construct. É exatamente como qualquer outra expressão e pode ser usada em qualquer contexto em que uma expressão C# é válida.It is just like any other expression and can be used in any context in which a C# expression is valid. Uma expressão de consulta consiste em um conjunto de cláusulas escritas em uma sintaxe declarativa semelhante ao SQL ou XQuery.A query expression consists of a set of clauses written in a declarative syntax similar to SQL or XQuery. Cada cláusula, por sua vez, contém uma ou mais expressões C# e essas expressões podem ser uma expressão de consulta ou conter uma expressão de consulta.Each clause in turn contains one or more C# expressions, and these expressions may themselves be either a query expression or contain a query expression.

Uma expressão de consulta deve começar com uma cláusula from e deve terminar com uma cláusula select ou group.A query expression must begin with a from clause and must end with a select or group clause. Entre a primeira cláusula from e a última cláusula select ou group, ela pode conter uma ou mais dessas cláusulas opcionais: where, orderby, join, let e até mesmo cláusulas from adicionais.Between the first from clause and the last select or group clause, it can contain one or more of these optional clauses: where, orderby, join, let and even additional from clauses. Você também pode usar a palavra-chave into para permitir que o resultado de uma cláusula join ou group sirva como a fonte para cláusulas de consulta adicionais na mesma expressão de consulta.You can also use the into keyword to enable the result of a join or group clause to serve as the source for additional query clauses in the same query expression.

Variável da consultaQuery variable

Em LINQ, uma variável de consulta é qualquer variável que armazena uma consulta em vez dos resultados de uma consulta.In LINQ, a query variable is any variable that stores a query instead of the results of a query. Mais especificamente, uma variável de consulta é sempre um tipo enumerável que produzirá uma sequência de elementos quando for iterada em uma instrução foreach ou uma chamada direta para seu método IEnumerator.MoveNext.More specifically, a query variable is always an enumerable type that will produce a sequence of elements when it is iterated over in a foreach statement or a direct call to its IEnumerator.MoveNext method.

O exemplo de código a seguir mostra uma expressão de consulta simples com uma fonte de dados, uma cláusula de filtragem, uma cláusula de ordenação e nenhuma transformação dos elementos de origem.The following code example shows a simple query expression with one data source, one filtering clause, one ordering clause, and no transformation of the source elements. A cláusula select termina a consulta.The select clause ends the query.

static void Main()
{
    // Data source.
    int[] scores = { 90, 71, 82, 93, 75, 82 };

    // Query Expression.
    IEnumerable<int> scoreQuery = //query variable
        from score in scores //required
        where score > 80 // optional
        orderby score descending // optional
        select score; //must end with select or group

    // Execute the query to produce the results
    foreach (int testScore in scoreQuery)
    {
        Console.WriteLine(testScore);
    }                  
}
// Outputs: 93 90 82 82      

No exemplo anterior, scoreQuery é uma variável de consulta, o que às vezes é chamado apenas de uma consulta.In the previous example, scoreQuery is a query variable, which is sometimes referred to as just a query. A variável de consulta não armazena nenhum dado de resultado real, que é produzido no loop foreach.The query variable stores no actual result data, which is produced in the foreach loop. E quando instrução foreach é executada, os resultados da consulta não são retornados pela variável de consulta scoreQuery.And when the foreach statement executes, the query results are not returned through the query variable scoreQuery. Em vez disso, eles são retornados pela variável de iteração testScore.Rather, they are returned through the iteration variable testScore. A variável scoreQuery pode ser iterada em um segundo loop foreach.The scoreQuery variable can be iterated in a second foreach loop. Ele produzirá os mesmos resultados contanto que nem ele nem a fonte de dados tenham sido modificados.It will produce the same results as long as neither it nor the data source has been modified.

Uma variável de consulta pode armazenar uma consulta que é expressada na sintaxe de consulta ou na sintaxe de método ou uma combinação das duas.A query variable may store a query that is expressed in query syntax or method syntax, or a combination of the two. Nos exemplos a seguir, queryMajorCities e queryMajorCities2 são variáveis de consulta:In the following examples, both queryMajorCities and queryMajorCities2 are query variables:

//Query syntax
IEnumerable<City> queryMajorCities =
    from city in cities
    where city.Population > 100000
    select city;


// Method-based syntax
IEnumerable<City> queryMajorCities2 = cities.Where(c => c.Population > 100000);

Por outro lado, os dois exemplos a seguir mostram variáveis que não são variáveis de consulta, embora sejam inicializadas com uma consulta.On the other hand, the following two examples show variables that are not query variables even though each is initialized with a query. Elas não são variáveis de consulta porque armazenam resultados:They are not query variables because they store results:

int highestScore =
    (from score in scores
     select score)
    .Max();

// or split the expression
IEnumerable<int> scoreQuery =
    from score in scores
    select score;

int highScore = scoreQuery.Max();
// the following returns the same result
int highScore = scores.Max();

List<City> largeCitiesList =
    (from country in countries
     from city in country.Cities
     where city.Population > 10000
     select city)
       .ToList();

// or split the expression
IEnumerable<City> largeCitiesQuery =
    from country in countries
    from city in country.Cities
    where city.Population > 10000
    select city;

List<City> largeCitiesList2 = largeCitiesQuery.ToList();

Para obter mais informações sobre as diferentes maneiras de expressar consultas, consulte Sintaxe de consulta e sintaxe de método em LINQ.For more information about the different ways to express queries, see Query syntax and method syntax in LINQ.

Tipagem explícita e implícita de variáveis de consultaExplicit and implicit typing of query variables

Esta documentação normalmente fornece o tipo explícito da variável de consulta para mostrar a relação de tipo entre a variável de consulta e a cláusula select.This documentation usually provides the explicit type of the query variable in order to show the type relationship between the query variable and the select clause. No entanto, você também pode usar a palavra-chave var para instruir o compilador a inferir o tipo de uma variável de consulta (ou qualquer outra variável local) em tempo de compilação.However, you can also use the var keyword to instruct the compiler to infer the type of a query variable (or any other local variable) at compile time. Por exemplo, o exemplo de consulta que foi mostrado anteriormente neste tópico também pode ser expressado usando a tipagem implícita:For example, the query example that was shown previously in this topic can also be expressed by using implicit typing:

// Use of var is optional here and in all queries.
// queryCities is an IEnumerable<City> just as 
// when it is explicitly typed.
var queryCities =
    from city in cities
    where city.Population > 100000
    select city;

Para obter mais informações, consulte Variáveis locais de tipo implícito e Relacionamentos de tipo em operações de consulta LINQ.For more information, see Implicitly typed local variables and Type relationships in LINQ query operations.

Iniciando uma expressão de consultaStarting a query expression

Uma expressão de consulta deve começar com uma cláusula from.A query expression must begin with a from clause. Especifica uma fonte de dados junto com uma variável de intervalo.It specifies a data source together with a range variable. A variável de intervalo representa cada elemento sucessivo na sequência de origem como a sequência de origem que está sendo percorrida.The range variable represents each successive element in the source sequence as the source sequence is being traversed. A variável de intervalo é fortemente tipada com base no tipo dos elementos na fonte de dados.The range variable is strongly typed based on the type of elements in the data source. No exemplo a seguir, como countries é uma matriz de objetos Country, a variável de intervalo também é tipada como Country.In the following example, because countries is an array of Country objects, the range variable is also typed as Country. Como a variável de intervalo é fortemente tipada, você pode usar o operador ponto para acessar todos os membros disponíveis do tipo.Because the range variable is strongly typed, you can use the dot operator to access any available members of the type.

IEnumerable<Country> countryAreaQuery =
    from country in countries
    where country.Area > 500000 //sq km
    select country;

A variável de intervalo está no escopo até a consulta ser encerrada com ponto e vírgula ou com uma cláusula continuation.The range variable is in scope until the query is exited either with a semicolon or with a continuation clause.

Uma expressão de consulta pode conter várias cláusulas from.A query expression may contain multiple from clauses. Use cláusulas from adicionais quando cada elemento na sequência de origem for uma coleção em si ou contiver uma coleção.Use additional from clauses when each element in the source sequence is itself a collection or contains a collection. Por exemplo, suponha que você tem uma coleção de objetos Country e cada um dos quais contém uma coleção de objetos City chamada Cities.For example, assume that you have a collection of Country objects, each of which contains a collection of City objects named Cities. Para consular os objetos City em cada Country, use duas cláusulas from como mostrado aqui:To query the City objects in each Country, use two from clauses as shown here:

IEnumerable<City> cityQuery =
    from country in countries
    from city in country.Cities
    where city.Population > 10000
    select city;

Para obter mais informações, consulte Cláusula from.For more information, see from clause.

Encerrando uma expressão de consultaEnding a query expression

Uma expressão de consulta deve ser encerrada com uma cláusula group ou uma cláusula select.A query expression must end with either a group clause or a select clause.

Cláusula groupgroup clause

Use a cláusula group para produzir uma sequência de grupos organizada por uma chave que você especificar.Use the group clause to produce a sequence of groups organized by a key that you specify. A chave pode ter qualquer tipo de dados.The key can be any data type. Por exemplo, a consulta a seguir cria uma sequência de grupos que contém um ou mais objetos Country e cuja chave é um valor char.For example, the following query creates a sequence of groups that contains one or more Country objects and whose key is a char value.

var queryCountryGroups =
    from country in countries
    group country by country.Name[0];

Para obter mais informações sobre o agrupamento, consulte Cláusula group.For more information about grouping, see group clause.

Cláusula selectselect clause

Use a cláusula select para produzir todos os outros tipos de sequências.Use the select clause to produce all other types of sequences. Uma cláusula select simples produz apenas uma sequência do mesmo tipo dos objetos contidos na fonte de dados.A simple select clause just produces a sequence of the same type of objects as the objects that are contained in the data source. Neste exemplo, a fonte de dados contém objetos Country.In this example, the data source contains Country objects. A cláusula orderby simplesmente classifica os elementos em uma nova ordem e a cláusula select produz uma sequência dos objetos Country reordenados.The orderby clause just sorts the elements into a new order and the select clause produces a sequence of the reordered Country objects.

IEnumerable<Country> sortedQuery =
    from country in countries
    orderby country.Area
    select country;

A cláusula select pode ser usada para transformar dados de origem em sequências de novos tipos.The select clause can be used to transform source data into sequences of new types. Essa transformação também é chamada de projeção.This transformation is also named a projection. No exemplo a seguir, a cláusula select projeta uma sequência de tipos anônimos que contém apenas um subconjunto dos campos no elemento original.In the following example, the select clause projects a sequence of anonymous types which contains only a subset of the fields in the original element. Observe que os novos objetos são inicializados usando um inicializador de objeto.Note that the new objects are initialized by using an object initializer.

// Here var is required because the query
// produces an anonymous type.
var queryNameAndPop =
    from country in countries
    select new { Name = country.Name, Pop = country.Population };

Para obter mais informações sobre todas as maneiras que uma cláusula select pode ser usada para transformar os dados de origem, consulte Cláusula select.For more information about all the ways that a select clause can be used to transform source data, see select clause.

Continuações com "into"Continuations with "into"

Você pode usar a palavra-chave into em uma cláusula select ou group para criar um identificador temporário que armazena uma consulta.You can use the into keyword in a select or group clause to create a temporary identifier that stores a query. Faça isso quando precisar executar operações de consulta adicionais em uma consulta após a operação de agrupamento ou seleção.Do this when you must perform additional query operations on a query after a grouping or select operation. No exemplo a seguir countries são agrupados de acordo com a população em intervalos de 10 milhões.In the following example countries are grouped according to population in ranges of 10 million. Depois que esses grupos são criados, cláusulas adicionais filtram alguns grupos e, em seguida, classificam os grupos em ordem crescente.After these groups are created, additional clauses filter out some groups, and then to sort the groups in ascending order. Para executar essas operações adicionais, a continuação representada por countryGroup é necessária.To perform those additional operations, the continuation represented by countryGroup is required.

// percentileQuery is an IEnumerable<IGrouping<int, Country>>
var percentileQuery =
    from country in countries
    let percentile = (int) country.Population / 10_000_000
    group country by percentile into countryGroup
    where countryGroup.Key >= 20
    orderby countryGroup.Key
    select countryGroup;

// grouping is an IGrouping<int, Country>
foreach (var grouping in percentileQuery)
{
    Console.WriteLine(grouping.Key);
    foreach (var country in grouping)
        Console.WriteLine(country.Name + ":" + country.Population);
}

Para obter mais informações, consulte into.For more information, see into.

Filtragem, ordenação e junçãoFiltering, ordering, and joining

Entre a cláusula from inicial e a cláusula select ou group final, todas as outras cláusulas (where, join, orderby, from, let) são opcionais.Between the starting from clause, and the ending select or group clause, all other clauses (where, join, orderby, from, let) are optional. Todas as cláusulas opcionais podem ser usadas várias vezes ou nenhuma vez no corpo de uma consulta.Any of the optional clauses may be used zero times or multiple times in a query body.

Cláusula wherewhere clause

Use a cláusula where para filtrar os elementos dos dados de origem com base em uma ou mais expressões de predicado.Use the where clause to filter out elements from the source data based on one or more predicate expressions. A cláusula where no exemplo a seguir tem um predicado com duas condições.The where clause in the following example has one predicate with two conditions.

IEnumerable<City> queryCityPop =
    from city in cities
    where city.Population < 200000 && city.Population > 100000
    select city;

Para obter mais informações, consulte Cláusula where.For more information, see where clause.

Cláusula orderbyorderby clause

Use a cláusula orderby para classificar os resultados em ordem crescente ou decrescente.Use the orderby clause to sort the results in either ascending or descending order. Você também pode especificar as ordens de classificação secundárias.You can also specify secondary sort orders. O exemplo a seguir executa uma classificação primária nos objetos country usando a propriedade Area.The following example performs a primary sort on the country objects by using the Area property. Em seguida, ele executa a classificação secundária usando a propriedade Population.It then performs a secondary sort by using the Population property.

IEnumerable<Country> querySortedCountries =
    from country in countries
    orderby country.Area, country.Population descending
    select country;

A palavra-chave ascending é opcional. Será a ordem de classificação padrão se nenhuma ordem for especificada.The ascending keyword is optional; it is the default sort order if no order is specified. Para obter mais informações, consulte Cláusula orderby.For more information, see orderby clause.

Cláusula joinjoin clause

Use a cláusula join para associar e/ou combinar elementos de uma fonte de dados com elementos de outra fonte de dados com base em uma comparação de igualdade entre as chaves especificadas em cada elemento.Use the join clause to associate and/or combine elements from one data source with elements from another data source based on an equality comparison between specified keys in each element. Na LINQ, as operações join são executadas em sequências de objetos cujos elementos são de tipos diferentes.In LINQ, join operations are performed on sequences of objects whose elements are different types. Após ter unido duas sequências, você deve usar uma instrução select ou group para especificar qual elemento armazenar na sequência de saída.After you have joined two sequences, you must use a select or group statement to specify which element to store in the output sequence. Você também pode usar um tipo anônimo para combinar propriedades de cada conjunto de elementos associados em um novo tipo para a sequência de saída.You can also use an anonymous type to combine properties from each set of associated elements into a new type for the output sequence. O exemplo a seguir associa objetos prod cuja propriedade Category corresponde a uma das categorias na matriz de cadeias de caracteres categories.The following example associates prod objects whose Category property matches one of the categories in the categories string array. Produtos cuja Category não corresponde a nenhuma cadeia de caracteres em categories são filtrados. A instrução select projeta um novo tipo cujas propriedades são tiradas de cat e prod.Products whose Category does not match any string in categories are filtered out. The select statement projects a new type whose properties are taken from both cat and prod.

var categoryQuery =
    from cat in categories
    join prod in products on cat equals prod.Category
    select new { Category = cat, Name = prod.Name };

Você também pode executar uma junção de grupo armazenando os resultados da operação join em uma variável temporária usando a palavra-chave into.You can also perform a group join by storing the results of the join operation into a temporary variable by using the into keyword. Para obter mais informações, consulte Cláusula join.For more information, see join clause.

Cláusula letlet clause

Use a cláusula let para armazenar o resultado de uma expressão, como uma chamada de método, em uma nova variável de intervalo.Use the let clause to store the result of an expression, such as a method call, in a new range variable. No exemplo a seguir, a variável de intervalo firstName armazena o primeiro elemento da matriz de cadeias de caracteres que é retornado pelo Split.In the following example, the range variable firstName stores the first element of the array of strings that is returned by Split.

string[] names = { "Svetlana Omelchenko", "Claire O'Donnell", "Sven Mortensen", "Cesar Garcia" };
IEnumerable<string> queryFirstNames =
    from name in names
    let firstName = name.Split(' ')[0]
    select firstName;

foreach (string s in queryFirstNames)
    Console.Write(s + " ");
//Output: Svetlana Claire Sven Cesar

Para obter mais informações, consulte Cláusula let.For more information, see let clause.

Subconsultas em uma expressão de consultaSubqueries in a query expression

Uma cláusula de consulta pode conter uma expressão de consulta, que às vezes é chamada de subconsulta.A query clause may itself contain a query expression, which is sometimes referred to as a subquery. Cada subconsulta começa com sua própria cláusula from que não necessariamente aponta para a mesma fonte de dados na primeira cláusula from.Each subquery starts with its own from clause that does not necessarily point to the same data source in the first from clause. Por exemplo, a consulta a seguir mostra uma expressão de consulta que é usada na instrução select para recuperar os resultados de uma operação de agrupamento.For example, the following query shows a query expression that is used in the select statement to retrieve the results of a grouping operation.

var queryGroupMax =
    from student in students
    group student by student.GradeLevel into studentGroup
    select new
    {
        Level = studentGroup.Key,
        HighestScore =
            (from student2 in studentGroup
             select student2.Scores.Average())
             .Max()
    };

Para obter mais informações, consulte Como executar uma subconsulta em uma operação de agrupamento.For more information, see How to: perform a subquery on a grouping operation.

Consulte tambémSee Also

Guia de programação em C#C# programming guide
Expressões de consulta LINQLINQ query expressions
Palavras-chave de consulta (LINQ)Query keywords (LINQ)
Visão geral de operadores de consulta padrãoStandard query operators overview