Compartilhar via


Noções básicas sobre expressões de consulta (Guia de Programação em C#)

O que é uma consulta e o que ele faz?

A consulta é um conjunto de instruções que descreve quais dados a recuperar de uma determinada fonte de dados (ou origens) e qual forma e a organização devem ter aos dados retornados. Uma query é diferenciada a partir dos resultados que ela produz.

Geralmente, os dados de origem são organizados logicamente como uma sequência de elementos do mesmo tipo. Uma tabela de um banco de dados SQL contém uma sequência de linhas. Da mesma forma, um ADO.NETDataTable contém uma seqüência de DataRow objetos.  Em um arquivo XML, existe uma "sequência" de elementos XML (apesar destes serem organizados hierarquicamente em uma estrutura de árvore). Uma coleçao na mémoria contém uma sequência de objetos.

Do ponto de vista do aplicativo, o tipo específico e a estrutura dos dados de origem original não é importante. O aplicativo sempre vê os dados de origem como um IEnumerable ou IQueryable coleção. Na LINQ to XML, os dados de origem são tornados visíveis como um IEnumerable<XElement>. In LINQ to DataSet, it is an IEnumerable<DataRow>. Na LINQ to SQL, é um IEnumerable ou IQueryable de quaisquer objetos personalizados que você definiu para representar os dados na tabela SQL.

Dada essa seqüência de origem, uma consulta pode fazer uma destas três coisas:

  • Recupere um subconjunto dos elementos para produzir uma nova seqüência sem modificar os elementos individuais. A consulta pode, em seguida, classificar ou agrupar a seqüência retornada de várias maneiras, como mostrado no exemplo a seguir (suponha scores é um int[]):

    IEnumerable<int> highScoresQuery =
        from score in scores
        where score > 80
        orderby score descending 
        select score;
    
  • Recuperar uma seqüência de elementos como no exemplo anterior, mas transformá-los para um novo tipo de objeto. Por exemplo, uma consulta pode recuperar somente os sobrenomes de certos registros de clientes em uma fonte de dados. Ou ele pode recuperar o registro completo e, em seguida, use-o para construir outro tipo de objeto na memória ou até mesmo dados XML antes de gerar a seqüência de resultado final. O exemplo a seguir mostra uma transformação de um int para um string. Observe o novo tipo de highScoresQuery.

    IEnumerable<string> highScoresQuery2 =
        from score in scores
        where score > 80
        orderby score descending 
        select String.Format("The score is {0}", score);
    
  • Recupere um valor singleton sobre dados de origem, tais como:

    • O número de elementos que coincidam com uma determinada condição.

    • O elemento que contém o valor maior ou menor.

    • O primeiro elemento corresponde a uma condição ou a soma dos valores específicos em um conjunto especificado de elementos. Por exemplo, o consulta a seguir retorna o número de pontuações mais de 80 a partir do scores matriz de inteiros:

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

    No exemplo anterior, observe o uso de parênteses em torno da expressão de consulta antes da chamada para o Count método. Você também pode expressar isso usando uma nova variável para armazenar o resultado de concreto. Essa técnica é mais legível, porque ele mantém a variável que armazenam a consulta separada da consulta que armazena um resultado.

    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 nos resultados para determinar o número de elementos retornados por highScoresQuery.

O que é uma expressão de consulta?

A expressão de consulta é uma consulta expressa na sintaxe de consulta. Uma expressão de consulta é uma construção de linguagem de primeira classe. Ele é exatamente como qualquer outra expressão e pode ser usado em qualquer contexto em que uma expressão de C# é válida. Uma expressão de consulta consiste em um conjunto de cláusulas escrito na sintaxe declarativa semelhante a SQL ou XQuery. Cada cláusula por sua vez contém uma ou mais expressões C# e essas expressões podem eles próprios ser uma expressão de consulta ou conter uma expressão de consulta.

Uma expressão de consulta deve começar com um de cláusula e deve terminar com um Selecionar ou grupo cláusula. Entre o primeiro from cláusula e a última select ou group cláusula, ele pode conter uma ou mais das seguintes cláusulas opcionais: onde, orderby, associação, permitem que e até mesmo adicionais de cláusulas. Você também pode usar o em palavra-chave para permitir que o resultado de uma join ou group cláusula para servir como a origem das cláusulas de consulta adicionais na mesma expressão de consulta.

Variável de consulta

Na LINQ, uma variável de consulta é qualquer variável que armazena um consulta em vez da resultados de uma consulta. Mais especificamente, uma variável de consulta é sempre um tipo enumerable que produzirá uma seqüência de elementos quando ele é iterado em um foreach instrução ou uma chamada direta para seus IEnumerator.MoveNext método.

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 sem transformação dos elementos de origem. O select cláusula termina a consulta.

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 é um variável de consulta, que às vezes é chamado como apenas um consulta. A variável de consulta não armazena nenhum dado do resultado real, que é produzido na foreach loop. E quando o foreach instrução é executada, os resultados da consulta não são retornados através da variável de consulta scoreQuery. Em vez disso, eles são devolvidos através da variável de iteração testScore. O scoreQuery variável pode ser iterado em um segundo foreach loop. Desde que foi modificada nem ele nem a fonte de dados, ele produzirá os mesmos resultados.

Uma variável de consulta pode armazenar uma consulta que é expressa na sintaxe de consulta ou sintaxe do método ou uma combinação dos dois. Nos exemplos a seguir, ambos queryMajorCities e queryMajorCities2 são variáveis de consulta:

//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, dois exemplos a seguir mostram as variáveis que não são variáveis de consulta, mesmo através de cada uma é inicializada com uma consulta. Eles não são variáveis de consulta porque eles armazenam resultados:

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();

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();

Dica

No LINQ documentação, variáveis que armazenam uma consulta tem a palavra "consulta" como parte de seus nomes.Variáveis que armazenam um resultado real não têm "query" em seus nomes.

Para obter mais informações sobre as diferentes maneiras para consultas express, consulte Sintaxe de consulta e sintaxe de método em LINQ (C#).

Explícitas e implícitas a digitação das variáveis de consulta

Esta documentação fornece geralmente do tipo explícito da variável de consulta para mostrar a relação de tipo entre a variável de consulta e o cláusula select. No entanto, você também pode usar o var palavra-chave para instruir o compilador para inferir o tipo de uma variável de consulta (ou qualquer outra variável local) em tempo de compilação. Por exemplo, o exemplo de consulta que foi mostrado anteriormente neste tópico também pode ser expresso por meio de digitação implícita:

// 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 (Guia de Programação em C#) e Relacionamentos de tipo em operações de consulta LINQ (C#).

Iniciando uma expressão de consulta

Uma expressão de consulta deve começar com um from cláusula. Especifica uma fonte de dados em conjunto com uma variável de intervalo. A variável de intervalo representa cada elemento sucessivo na seqüência de origem, como a seqüência de origem é sendo atravessada. A variável de intervalo é fortemente tipada com base no tipo de elementos na fonte de dados. No exemplo a seguir, porque countries é uma matriz de Country objetos, a variável de intervalo também é digitada como Country. Porque a variável de intervalo tem rigidez de tipos, você pode usar o operador ponto para acessar quaisquer membros disponíveis do tipo.

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

A variável de intervalo está no escopo até que a consulta será finalizada com um ponto e vírgula ou com um continuação cláusula.

Uma expressão de consulta pode conter vários from cláusulas. Uso adicional from cláusulas quando cada elemento da seqüência de origem é uma coleção em si ou contém uma coleção. Por exemplo, suponha que você tem uma coleção de Country objetos, cada um deles contém uma coleção de City objetos nomeados Cities. A consulta a City objetos em cada Country, use dois from cláusulas, como mostrado aqui:

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 (Referência de C#).

Final de uma expressão de consulta

Uma expressão de consulta deve terminar com um um select cláusula ou um group cláusula.

Cláusula de grupo.

Use o group cláusula para produzir uma seqüência de grupos organizados por uma chave que você especificar. A chave pode ser qualquer tipo de dados. Por exemplo, a consulta a seguir cria uma seqüência de grupos que contém um ou mais Country de objetos e cuja chave é um char valor.

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

Para obter mais informações sobre o agrupamento, consulte Cláusula group (Referência de C#).

Cláusula Select

Use o select cláusula para produzir todos os outros tipos de seqüências. Uma simples select cláusula produz apenas uma seqüência do mesmo tipo de objetos como os objetos que estão contidos na fonte de dados. Neste exemplo, a fonte de dados contém Country objetos. O orderby cláusula classifica apenas os elementos em uma nova ordem e o select cláusula produz uma seqüência do reordenados Country objetos.

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

O select cláusula pode ser usada para transformar dados de origem em seqüências de novos tipos. Essa transformação também é chamada um projeção. No exemplo a seguir, o select cláusula projetos uma seqüência de tipos anônimos que contém somente um subconjunto dos campos no elemento original. Observe que os novos objetos são inicializados usando um inicializador de objeto.

// 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 as formas que um select cláusula pode ser usada para transformar os dados de origem, consulte Cláusula select (Referência de C#).

Continuação com "em"

Você pode usar o into palavra-chave em um select ou group cláusula para criar um identificador temporário que armazena uma consulta. Faça isso quando você deve realizar operações de consulta adicional em uma consulta após um agrupamento ou selecionar a operação. No exemplo a seguir countries são agrupados de acordo com a população em intervalos de 10 milhões. Depois que esses grupos são o filtro criado, additional cláusulas check-out de alguns grupos e, em seguida, para classificar os grupos em crescente da ordem. Para executar essas operações adicionais, a continuação é representado por countryGroup é necessária.

// percentileQuery is an IEnumerable<IGrouping<int, Country>> 
var percentileQuery =
    from country in countries
    let percentile = (int) country.Population / 10000000
    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 (Referência de C#).

Filtragem, ordenação e ingressando em

Entre o início from cláusula e a terminação select ou group cláusula, todas as outras cláusulas (where, join, orderby, from, let) são opcionais. Qualquer uma das cláusulas opcionais pode ser usado nenhuma vez ou várias vezes no corpo de uma consulta.

onde cláusula

Use o where cláusula para filtrar elementos dos dados de origem com base em uma ou mais expressões de predicado. O where cláusula no exemplo a seguir possui duas predicados.

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 (Referência de C#).

OrderBy cláusula

Use o orderby cláusula para classificar os resultados em crescente ou decrescente. Você também pode especificar as ordens de classificação secundária. O exemplo a seguir executa uma classificação primária sobre o country objetos usando o Area propriedade. Em seguida, realiza uma ordenação secundária usando o Population propriedade.

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

O ascending palavra-chave é opcional. é a ordem de classificação padrão se nenhuma ordem for especificada. Para obter mais informações, consulte Cláusula orderby (Referência de C#).

Cláusula de associação

Use o join cláusula 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 chaves especificadas em cada elemento. Na LINQ, as operações de associação são executadas em seqüências de objetos cujos elementos são tipos diferentes. Após ter adicionado duas seqüências, você deve usar um select ou group instrução para especificar qual elemento para armazenar na seqüência de saída. Você também pode usar um tipo anônimo para combinar a propriedades de cada conjunto de elementos associados em um novo tipo de seqüência de saída. O exemplo a seguir associa prod objetos cuja Category propriedade corresponde a uma das categorias a categories matriz de cadeia de caracteres. Produtos cujo Category não coincide com qualquer seqüência de caracteres em categories são filtrados. O select instrução projeta um novo tipo cujas propriedades são tiradas de ambos cat e 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 associação de grupo, armazenando os resultados da join operação em uma variável temporária usando o em palavra-chave. Para obter mais informações, consulte Cláusula join (Referência de C#).

permitir que a cláusula

Use o let cláusula para armazenar o resultado de uma expressão, como, por exemplo, uma chamada de método em uma nova variável de intervalo. No exemplo a seguir, a variável de intervalo firstName armazena o primeiro elemento da matriz de seqüências de caracteres que é retornado por Split.

string[] names = { "Svetlana Omelchenko", "Claire O'Donnell", "Sven Mortensen", "Cesar Garcia" };
IEnumerable<string> queryFirstNames =
    from name in names
    let firstName = name.Split(new char[] { ' ' })[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 (Referência de C#).

Subconsultas em uma expressão de consulta

Se uma cláusula de consulta pode conter uma expressão de consulta, às vezes é chamada de um subconsulta. Cada subconsulta inicia com seu próprio from que não necessariamente aponta para a mesma fonte de dados na primeira cláusula from cláusula. 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.

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 (Guia de Programação em C#).

Consulte também

Conceitos

Guia de Programação em C#

Expressões de consulta LINQ (Guia de Programação em C#)

Visão geral de operadores de consulta padrão

Outros recursos

LINQ (Consulta Integrada à Linguagem)

Palavras-chave de consulta (Referência de C#)