Para este artigo estarei usando a versão Community 2015 do Visual Studio, .NET Framework 4.5 e SQL Server 2012. É necessário que você já tenha um conhecimento mínimo de linguagem C# e SQL.
Todos os exemplos são em Console Application, uma vez que a intenção é não é criar algo sofisticado, mas apenas elucidar os conceitos principais sobre o tema.
O que é LINQ?
LINQ (Language Integrated Query) ou Linguagem de Consulta Integrada é um recurso do .NET Framework que permite, através de algumas linguagens .NET, realizar consultas em estrutura de dados, base de dados, documentos XML, coleção de objetos, utilizando uma sintaxe semelhante a da linguagem SQL. Funciona como uma camada intermediária entre a fonte de dados e a linguagem.

Fonte: msdn.microsoft
LINQ foi introduzido no Visual Studio 2008 na versão 3.5 do .NET Framework (faz tempo, não?) e desenvolvido pelo mesmo engenheiro de software responsável pela criação do Delphi e do C#, Anders Hejlsberg.
Lambda, sintaxe de consulta, sintaxe de método
Uma expressão lambda é a forma como a expressão de consulta é construída, tem sua origem no Cálculo Lambda, que oferece os fundamentos matemáticos.
c => (c + 2) > 5
O símbolo “=>” é o operador Lambda que é lido como “vai para (goes to)”, com a variável a esquerda e expressão a direita.
As sintaxes de consulta e de método são semanticamente idênticas, apesar de algumas pessoas acharem a primeira mais legível e fácil de compreender.
A sintaxe de consulta é criada usando operadores consulta padrão em LINQ e convertida em chamadas de método no momento da execução (CLR).
var consulta = from l in livros
where l.genero == "Ficção Científica"
orderby l.Titulo
select l;
Na sintaxe de método as consultas são expressas como chamadas de métodos.
var consulta = livros
.Where(l => l.geneto == "Ficção Científica")
.OrderBy(m => m.Titulo);
Execução Imediata Vs Execução Adiada
Em LINQ uma consulta que retorna uma sequência de valores não é executada até que os dados sejam requisitados e acessados durante a iteração, isso é chamado de execução adiada ou deferred execution. Repare que no exemplo acima a variável não armazena o resultado (livros do gênero Ficção Científica), mas sim uma estrutura de dados chamada “Árvore de Expressão ou Expression Tree”, contendo informações sobre a origem dos dados (tabela, coleção, arquivo) , os comandos da consulta e qual resultado deve ser retornado.
Em contrapartida, consultas do tipo singleton, ou seja, que retornam um valor único são executadas imediatamente, como Count, First, Average, Min e Max. Para forçar a execução imediada, caso queira armazenar os resultados, você pode chamar os métodos ToList<T>, ToDictionary ou ToArray<T>. Exemplo:
var consulta = (from a in clientes where a.Cidade == "São Paulo").ToList();
LINQ Provider (LINQ to …)
É o LINQ Provider que vai nos permitir escrever as consultas para as operações do CRUD e existem 5 tipos:
- LINQ to Objects
- LINQ to XML(XLINQ)
- LINQ to DataSet
- LINQ to SQL (DLINQ)
- LINQ to Entities
LINQ to Objects
Antigamente era necessário percorrer uma coleção através do laço foreach para recuperar algum elemento, agora só precisamos realizar uma consulta informando o que se deseja recuperar, para isso é preciso de uma referência ao namespace System.Data.Linq e que a coleção implemente a interface IEnumerable (ou IEnumerable<T>), como em Arrays, listas genéricas, dicionários, etc. Vejamos um exemplo:
using System;
using System.Collections.Generic;
using System.Linq;
namespace Providers
{
class LINQToObject
{
static void Main()
{
// Fonte de dados
int[] numeros = new int[] { 15, 20, 35, 40 };
// Expressão de consulta
IEnumerable<int> consulta = from n in numeros
where n % 2 == 0
select n;
Console.Write("Números pares: ");
// Executa a consulta
foreach (int i in consulta)
{
Console.Write(i + " ");
}
Console.ReadLine();
}
}
}
O resultado será “Números pares: 20 40″. Notou a semelhança com SQL? Especificamos a fonte de dados “numeros” e uma variável “n” para indicar o elemento atual.
LINQ to XML
Para este exemplo crie um novo documento chamado artigos.xml e cole o código abaixo, será nossa fonte de dados. Em seguida mova para o diretório do projeto (csproj).
<?xml version="1.0" encoding="utf-8" ?>
<artigos>
<artigo dia="17" mes="07" ano="2014">
<id>1</id>
<titulo>Análise Galaxy Tab S2 9,7</titulo>
<url>http://exemplo.com/artigo1</url>
<descricao>Desc 1</descricao>
</artigo>
<artigo dia="02" mes="05" ano="2014">
<id>2</id>
<titulo>Confira as novidades da CES 2014</titulo>
<url>http://exemplo.com/artigo2</url>
<descricao>Desc 2</descricao>
</artigo>
<artigo dia="02" mes="03" ano="2015">
<id>3</id>
<titulo>Fique por dentro de tudo que movimenta o setor de Cloud Computing</titulo>
<url>http://exemplo.com/artigo3</url>
<descricao>Desc 3</descricao>
</artigo>
</artigos>
O que faremos a seguir é carregar nosso documento na memória e realizar a consulta, para essa tarefa duas classes vão nos auxiliar, XDocument e XElement, ambas do namespace System.Xml.Linq. Para o resultado da consulta criaremos uma lista de objetos do tipo Artigo.
using System;
using System.Linq;
using System.Xml.Linq;
namespace Providers
{
class Artigo
{
public int Id { get; set; }
public string Titulo { get; set; }
public DateTime Data { get; set; }
public string Url { get; set; }
public string Descricao { get; set; }
public Artigo(XElement artigo)
{
Id = Convert.ToInt32(artigo.Element("id").Value);
Titulo = artigo.Element("titulo").Value;
Data = new DateTime(
int.Parse(artigo.Attribute("ano").Value),
int.Parse(artigo.Attribute("mes").Value),
int.Parse(artigo.Attribute("dia").Value)
);
Url = artigo.Element("url").Value;
Descricao = artigo.Element("descricao").Value;
}
}
class LINQToXML
{
static void Main()
{
// Carrega o arquivo xml
XDocument xml = XDocument.Load(@"....artigos.xml");
// Armazena cada nó/elemento do tipo artigo
var artigos = xml.Elements("artigos").Elements("artigo");
// Realiza a consulta filtrando os resultados
var consulta = from p in artigos
where (int)p.Attribute("ano") == 2014 && p.Element("titulo").Value.Contains("Análise")
select new Artigo(p);
// Percorre os resultados e exibe no console
foreach (var artigo in consulta)
{
Console.WriteLine("Título: {0}nPublicado em: {1}nUrl: {2}nDescricão: {3}nn",
artigo.Titulo, artigo.Data.ToShortDateString(), artigo.Url, artigo.Descricao);
}
Console.ReadLine();
}
}
}
XDocument fornece os métodos Load para carregar o documento e Elements. O método Elements sempre irá retornar uma coleção dos elementos filhos do elemento passado como parâmetro, ou seja, se o nome do parâmetro é “artigos” os elementos filhos serão todos os do tipo “artigo”.
Nesta consulta filtramos e selecionamos todos os artigos do ano de 2014 que contém a palavra “Análise” na propriedade Value do elemento titulo. Após obter os resultados percorremos a lista e exibimos os dados no console.
LINQ to DataSet
Para o artigo não ficar mais extenso vamos criar um DataSet simples na mão via código, representando os produtos de um mercado.
using System;
using System.Linq;
using System.Data;
namespace Providers
{
class LINQtoDataSet
{
static void Main()
{
// Objeto DataSet
DataSet ds = new DataSet("Mercado");
// Criando a tabela de produtos
var dtProdutos = new DataTable("Produtos");
dtProdutos.Columns.Add("Id", Type.GetType("System.Int32"));
dtProdutos.Columns.Add("Nome", Type.GetType("System.String"));
dtProdutos.Columns.Add("Preco", Type.GetType("System.Decimal"));
ds.Tables.Add(dtProdutos);
// Populamos a tabela com três produtos
DataRow drProdutos = dtProdutos.NewRow();
drProdutos["Id"] = 1;
drProdutos["Nome"] = "Sabão em pó";
drProdutos["Preco"] = 5.69;
dtProdutos.Rows.Add(drProdutos);
drProdutos = dtProdutos.NewRow();
drProdutos["Id"] = 2;
drProdutos["Nome"] = "Farinha de trigo";
drProdutos["Preco"] = 3.29;
dtProdutos.Rows.Add(drProdutos);
drProdutos = dtProdutos.NewRow();
drProdutos["Id"] = 3;
drProdutos["Nome"] = "Macarrão Spaghetti";
drProdutos["Preco"] = 5.55;
dtProdutos.Rows.Add(drProdutos);
var consulta =
from produto in dtProdutos.AsEnumerable()
select new
{
Nome = produto.Field<string>("Nome"),
Preco = produto.Field<decimal>("Preco")
};
Console.WriteLine("-- Produtos --");
foreach (var produto in consulta)
{
Console.WriteLine("{0} : R$ {1}", produto.Nome, produto.Preco);
}
Console.ReadLine();
}
}
}
Neste caso, sem muitas novidades. A classe de DataTable não implementa a interface IEnumerable<T>, portanto para realizar uma consulta LINQ precisamos chamar o método AsEnumerable e para acessar os valores das colunas utilizamos o método Field passando um parâmetro genérico que especifica o tipo de retorno da coluna.
LINQ to SQL
Antes de prosseguir utilize este script para gerar as tabelas no SQL Server.
Usar LINQ to SQL nos permite gerenciar dados relacionais como objetos por meio do mapeamento objeto-relacional O/RM, ou seja, as tabelas do banco de dados são representadas por classes e os registros de cada tabela como instâncias destas classes. Já as consultas criadas em sintaxe LINQ são convertidas em código T-SQL, a desvantagem é que só funciona com SQL Server 😦
Deste processo fazem parte três componentes:
- LINQ to SQL API: envia o pedido de consulta para o LINQ to SQL Provider.
- LINQ to SQL Provider: converte a consulta para T-SQL e envia ao ADO Provider.
- ADO Provider: Após executar a consulta encaminha o resultado (DataReader) de volta ao LINQ to SQL Provider que converte em um objeto.
Para se comunicar com o banco faremos uso da classe DataContext, que é responsável por:
- Criar conexão com o banco de dados;
- Acessar dados;
- Converter objetos para consulta SQL e vice-versa.
Certo, mãos a obra:
Vamos realizar a conexão com o banco de dados clicando em View -> Server Explorer -> Data Connections -> Connect to Database.

Em seguida clique em Project -> Add New Item e escolha LINQ to SQL Classes, com o nome Empresa.dbml

Selecione as tabelas do banco e arraste para o DBML.

Adicione uma referência a System.Configuration e no arquivo App.config, renomeie a connection string para EmpresaConnectionString.
Precisamos agora “codificar a mágica” de interação com o banco:
using System;
using System.Linq;
using System.Configuration;
namespace Providers
{
class LinqToSQL
{
static void Main(string[] args)
{
string connectionString = ConfigurationManager.ConnectionStrings["EmpresaConnectionString"].ConnectionString;
// Objeto que herda as características de DataContext
EmpresaDataContext db = new EmpresaDataContext(connectionString);
//----------------------------------------------------------------------
// Insert
Funcionario novoFuncionario = new Funcionario();
novoFuncionario.Nome = "Marcelo";
novoFuncionario.Email = "marcelo@email.com";
novoFuncionario.Endereco = "Rua Vergueiro, 44";
novoFuncionario.FkProfissao = 4;
// Insere um novo registro na tabela Funcionarios
db.Funcionarios.InsertOnSubmit(novoFuncionario);
//----------------------------------------------------------------------
// Update
// Busca um funcionário existente e atualiza o endereço
var funcionario = db.Funcionarios.Where(a => a.Nome == "Carlos").FirstOrDefault();
if (funcionario != null) funcionario.Endereco = "Rua Antônio Gomes, 22";
//----------------------------------------------------------------------
// Delete
// Busca um funcionário existente e o remove
var exFuncionario = db.Funcionarios.Where(a => a.Id == 2).FirstOrDefault();
if (exFuncionario != null) db.Funcionarios.DeleteOnSubmit(exFuncionario);
//----------------------------------------------------------------------
// Envia as alterações
db.SubmitChanges();
// Percorre a tabela de funcionários e exibe os dados no console
foreach (Funcionario f in db.Funcionarios)
{
Console.WriteLine("Nome: {0}nEmail: {1}nEndereço: {2}nProfissão: {3}",
f.Nome, f.Email, f.Endereco, f.Profissao.Nome);
Console.WriteLine("n----------------------------------------------------------");
}
Console.ReadLine();
}
}
}
Linq To Entities
Antes de prosseguir utilize este script para gerar as tabelas no SQL Server.
Segue a mesma ideia do LINQ to SQL porém usando Entity Framework e dentre as vantagens temos a possibilidade de trabalhar com diferentes banco de dados como SQL Server, IBM DB2, Oracle, SQL Azure, etc.
Vamos lá, adicione uma referência a System.Data.Entity e em seguida clique em Project -> Add New Item e escolha ADO.NET Entity Data Model, com o nome Empresa.

Selecione a opção EF Designer from database.

Selecione a string de conexão com o banco de dados Empresa ou clique em New Connection para criar uma nova conexão, caso não exista.

Por fim selecione os objetos do banco de dados e clique no botão Finish.

Se tudo correu bem ao término do assistente veremos a janela do Entity Framework Designer exibindo o diagrama do banco de dados, através dele poderíamos modificar entidades, associações, mapeamentos e relacionamentos.

Legal, hora de partir para o código:
using System;
using System.Linq;
namespace Providers
{
class LinqToEntities
{
static void Main()
{
using (var context = new EmpresaEntities())
{
// Insert
Funcionario novoFuncionario = new Funcionario();
novoFuncionario.Nome = "Lucas";
novoFuncionario.Email = "lucas@email.com";
novoFuncionario.Endereco = "Rua José de Azevedo, 422";
novoFuncionario.FkProfissao = 3;
// Insere um novo registro na tabela Funcionarios
context.Funcionario.Add(novoFuncionario);
//----------------------------------------------------------------------
// Update
// Busca um funcionário existente e atualiza o endereço
var funcionario = context.Funcionario.Where(a => a.Nome == "Julia").FirstOrDefault();
if (funcionario != null) funcionario.Email = "julia_123@email.com";
//----------------------------------------------------------------------
// Delete
// Busca um funcionário existente e o remove
var exFuncionario = context.Funcionario.Where(a => a.Id == 5).FirstOrDefault();
if (exFuncionario != null) context.Funcionario.Remove(exFuncionario);
//----------------------------------------------------------------------
var funcionarios = context.Funcionario.ToList();
funcionarios.ForEach(a => Console.WriteLine("Nome:{0}nEmail:{1}nEndereço:{2}n", a.Nome, a.Email, a.Endereco));
Console.ReadLine();
}
}
}
}
Bom pessoal é isso, procurei abordar os aspectos principais, ainda poderia falar sobre o uso de delegates, mas prefiro deixar para um outro artigo, então bons estudos e até a próxima!
