Compartilhar via


Introdução a consultas LINQ (C#)

Uma consulta é uma expressão que recupera dados de uma origem de dados. Geralmente, as consultas são expressas em uma linguagem de consulta especializada. Os idiomas diferentes foram desenvolvidos ao longo do tempo para os diversos tipos de fontes de dados, por exemplo, bancos de dados relacionais e XQuery para XML. Portanto, os desenvolvedores precisaram aprender uma nova linguagem de consulta para cada tipo de fonte de dados ou formato de dados que devem dar suporte. O LINQ simplifica esta situação oferecendo um modelo mais simples e consistente para trabalhar com dados em vários tipos de fontes de dados e formatos. Em uma consulta LINQ, você sempre trabalha com objetos. Você usa os mesmos padrões de codificação básica para consultar e transformar dados em documentos XML, em bases de dados SQL, em datasets de ADO.NET, em coleções do .NET, e em qualquer outro formato para o qual um provedor de LINQ está disponível.

Três Partes de uma Operação de Consulta

Todas as operações de consulta de LINQ consistem em três diferentes ações:

  1. Obter uma fonte de dados.

  2. Criar a consulta.

  3. Executar a consulta.

O exemplo a seguir mostra como as três partes de uma operação query são expressas no código-fonte. O exemplo usa uma matriz de inteiros como uma fonte de dados para sua conveniência. No entanto, os mesmos conceitos se aplicam também a outras fontes de dados. Este exemplo é conhecido em todo o restante deste tópico.

class IntroToLINQ
{        
    static void Main()
    {
        // The Three Parts of a LINQ Query: 
        //  1. Data source. 
        int[] numbers = new int[7] { 0, 1, 2, 3, 4, 5, 6 };

        // 2. Query creation. 
        // numQuery is an IEnumerable<int> 
        var numQuery =
            from num in numbers
            where (num % 2) == 0
            select num;

        // 3. Query execution. 
        foreach (int num in numQuery)
        {
            Console.Write("{0,1} ", num);
        }
    }
}

A ilustração a seguir mostra a operação de consulta concluída. No LINQ, a execução da consulta é distinta da própria consulta; em outras palavras, você não recuperou os dados simplesmente criando uma variável de consulta.

Concluir a operação de consulta do LINQ

A Fonte de Dados

No exemplo anterior, como a fonte de dados é uma matriz, ela dá suporte implícito à interface genérica IEnumerable. Esse fato significa que pode ser consultado com o LINQ. Uma consulta é executada em uma instrução de foreach , e foreach e requer IEnumerable ou IEnumerable. Tipos que oferecem suporte IEnumerable ou uma interface derivada como IQueryable genérico é chamada de tipos consultáveis.

Um tipo que pode ser consultado não requer qualquer alteração ou tratamento especial para servir como uma fonte de dados de LINQ. Se os dados de origem não estiverem mais na memória como um tipo consultável, o provedor do LINQ deverá representá-los como tal. Por exemplo, LINQ to XML carrega um documento XML em um tipo XElement consultável:

// Create a data source from an XML document. 
// using System.Xml.Linq;
XElement contacts = XElement.Load(@"c:\myContactList.xml");

Com LINQ to SQL, você primeiro cria o mapeamento do objeto relacional em tempo de design manualmente ou usando Designer Relacional de Objetos. Você escreve suas consultas em objetos, e no tempo de execução LINQ to SQL trata a comunicação com o banco de dados. No exemplo a seguir, Customers representa uma tabela específica no banco de dados e o tipo do resultado da consulta, IQueryable, deriva de IEnumerable.

Northwnd db = new Northwnd(@"c:\northwnd.mdf");

// Query for customers in London.
IQueryable<Customer> custQuery =
    from cust in db.Customers
    where cust.City == "London"
    select cust;

Para obter mais informações sobre como criar tipos específicos de fontes de dados, consulte a documentação de vários provedores do LINQ . No entanto, a regra básica é muito simples: uma fonte de dados LINQ é qualquer objeto que ofereça suporte à interface genérica IEnumerable ou a uma interface que herde dela.

Dica

Tipos como ArrayList que oferecem suporte à interface não genérica de IEnumerable também podem ser usados como fontes de dados LINQ.Para obter mais informações, consulte Como consultar um ArrayList com LINQ.

A Consulta

A consulta especifica quais informações recuperar de uma ou mais fontes de dados. Opcionalmente, uma consulta também especifica como essas informações devem ser classificadas, agrupadas e moldadas antes de serem retornadas. Uma consulta é armazenada em uma variável de consulta e inicializada com uma expressão de consulta. Para tornar mais fácil escrever consultas, C# introduziu uma nova sintaxe da consulta.

A consulta no exemplo anterior retorna todos os números pares da matriz de inteiros. A expressão de consulta contém três cláusulas: from, where e select. (Se você estiver familiarizado com o SQL, você terá observado que a ordem das cláusulas é o inverso da ordem no SQL.) A cláusula from especifica a fonte de dados, a cláusula where aplica o filtro e a cláusula select especifica o tipo dos elementos retornados. Essas e outras cláusulas de consulta são discutidas em detalhes na seção Expressões de consulta LINQ (Guia de Programação em C#). Por ora, o ponto importante é que em LINQ, a variável de consulta não toma nenhuma ação e não retorna dados. Simplesmente armazena as informações necessárias para produzir os resultados quando a consulta é executada em ponto posterior. Para obter mais informações sobre como as consultas são construídas nos bastidores, consulte Visão geral de operadores de consulta padrão.

Dica

As consultas também podem ser expressas usando a sintaxe do método.Para obter mais informações, consulte Sintaxe de consulta e sintaxe de método em LINQ (C#).

Execução da Consulta

Execução Adiada

Conforme observado anteriormente, a variável de consulta armazena somente os comandos de consulta. A execução real da consulta é adiada até que você itere a variável de consulta em uma instrução foreach. Esse conceito é conhecido como execução adiada e é demonstrado no exemplo a seguir:

//  Query execution.  
foreach (int num in numQuery)
{
    Console.Write("{0,1} ", num);
}

A instrução foreach também é onde os resultados da consulta são recuperados. Por exemplo, na consulta anterior, a variável de iteração num armazena cada valor (um por vez) na sequência retornada.

Como a variável de consulta nunca mantém os resultados da consulta, você pode executá-la com a frequência que desejar. Por exemplo, você pode ter um banco de dados que esteja sendo atualizado continuamente por um aplicativo separado. Em seu aplicativo, você pode criar uma consulta que recupera os dados mais recentes, e ela poderia ser repetidamente executada em algum intervalo para recuperar resultados diferentes a cada vez.

Forçando Execução Imediata

As consultas que executam funções de agregação em um intervalo de elementos de origem, devem primeiramente ser iteradas nesses elementos. Exemplos de tais consultas são Count, Max, Average e First. Eles são executados sem uma instrução foreach explícita, porque a consulta em si deve usar foreach para retornar um resultado. Observe também que esses tipos de consultas retornam um único valor, não uma coleção IEnumerable. A consulta a seguir retorna uma contagem dos números pares na matriz de origem:

var evenNumQuery = 
    from num in numbers
    where (num % 2) == 0
    select num;

int evenNumCount = evenNumQuery.Count();

Para forçar a execução imediata de qualquer consulta e armazenar em cachê seus resultados, você pode chamar os métodos de ToList``1 ou de ToArray``1.

List<int> numQuery2 =
    (from num in numbers
     where (num % 2) == 0
     select num).ToList();

// or like this: 
// numQuery3 is still an int[] 

var numQuery3 =
    (from num in numbers
     where (num % 2) == 0
     select num).ToArray();

Você também pode forçar a execução colocando o loop de foreach imediatamente após a expressão de consulta. No entanto, chamando ToList ou ToArray você também armazena todos os dados em cache em um único objeto de coleção.

Consulte também

Tarefas

Instruções passo a passo: escrevendo consultas em C# (LINQ)

Exemplos LINQ

Referência

foreach, in (Referência de C#)

Conceitos

Visão geral do designer do/R

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

Outros recursos

Introdução a LINQ em C#

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

Vídeo do LINQ e execução adiada