Banco de Dados

28 mar, 2018

Convertendo consultas T-SQL em LINQ

Publicidade

Introdução

Se você já teve e/ou tem bastante vivência com a linguagem T-SQL e hoje se depara com o um software que tem um ORM para fazer as transações com o banco de dados, pode ser que apareçam algumas dúvidas sobre como “converter” uma query T-SQL na “linguagem” que o ORM entende.

Se você se deparar com essa situação e tiver alguma dúvida quanto à alguma consulta que precisa converter, esse artigo é destinado a você.

Nesse artigo vamos utilizar o Entity Framework como ORM e a linguagem LINQ do Entities, que permite aos desenvolvedores escreverem consultas nesse modelo usando VB ou C#.

Abaixo, segue o modelo que utilizei para facilitar o entendimento das consultas.

1. Select com um TOP

T-SQL

SELECT TOP 2 Nome FROM Artista;

LINQ

var result = (from a in context.Artista select a.Nome).Take(2);

LAMBDA

var result = context.Artista.Select(a => a.Nome).Take(2);

2. Select com WHERE

T-SQL

SELECT Nome FROM Artista WHERE Nome = ‘Led Zeppelin’;

LINQ

var result = (from a in context.Artista 
                    where a.Nome.Equals(“Led Zeppelin”) 
                    select a.Nome).ToList();

LAMBDA

var result = context.Artista
                    .Where(a => a.Nome.Equals(“Led Zeppelin”))
                    .Select(a => a.Nome).ToList();

3. Select com INNER JOIN

T-SQL

SELECT a.Nome, al.Titulo FROM Artista a 
       		INNER JOIN Album al ON al.ArtistaId = a.ArtistaId;

LINQ

var result = (from a in context.Artista
            join al in context.Album on a.ArtistaId equals al.ArtistaId
            select new
            {
                a.Nome,
                al.Titulo
            }).ToList();

LAMBDA

var result = context.Artista
            .Join(context.Album, artista => artista.ArtistaId, album => album.ArtistaId,
            (artista, album) => new { Artista = artista, Album = album })
            .Select(a => new { 
                Nome = a.Artista.Nome, 
                Titulo = a.Album.Titulo 
            }).ToList();

4. Select com duas condições no mesmo Inner Join

T-SQL

SELECT DISTINCT a.Nome, al.Titulo FROM Artista a 
        		INNER JOIN Album al ON al.ArtistaId = a.ArtistaId AND al.Titulo = a.Nome;

LINQ

var result = (from a in context.Artista
            join al in context.Album on
            new { C1 = a.ArtistaId, C2 = a.Nome } equals 
            new { C1 = al.ArtistaId, C2 = al.Titulo }
            select new
            {
                a.Nome,
                al.Titulo
            }).ToList();

LAMBDA

var result = context.Artista
        .Join(context.Album, artista => new { C1 = artista.ArtistaId, C2 = artista.Nome }, 
            album => new { C1 = album.ArtistaId, C2 = album.Titulo },
            (artista, album) => new { Artista = artista, Album = album })
        .Select(a => new { 
            Nome = a.Artista.Nome, 
            Titulo = a.Album.Titulo 
        }).ToList();

5. Select com dois INNER JOINS

T-SQL

SELECT a.Nome, al.Titulo, f.Nome FROM Artista a
        		INNER JOIN Album al ON al.ArtistaId = a.ArtistaId
        		INNER JOIN Faixa f ON f.AlbumId = al.AlbumId;

LINQ

var result = (from a in context.Artista
        join al in context.Album on a.ArtistaId equals al.ArtistaId
        join f in context.Faixa on al.AlbumId equals f.AlbumId
        select new
        {
            Artista = a.Nome,
            Album = al.Titulo,
            Faixa = f.Nome
         }).ToList();

LAMBDA

var result = context.Artista
        .Join(context.Album, artista => artista.ArtistaId, album => album.ArtistaId,
            (artista, album) => new { Artista = artista, Album = album })
        .Join(context.Faixa, album => album.Album.AlbumId, faixa => faixa.AlbumId,
            (album, faixa) => new { Album = album, Faixa = faixa })
        .Select(a => new { 
            Nome = a.Album.Artista.Nome, 
            Titulo = a.Album.Album.Titulo, 
            Faixa = a.Faixa.Nome 
        }).ToList();

6. Select com LEFT JOIN

T-SQL

SELECT a.Nome, al.Titulo FROM Artista a
        		LEFT JOIN Album al ON al.ArtistaId = a.ArtistaId;

LINQ

var result = (from a in context.Artista
            join al in context.Album on a.ArtistaId equals al.ArtistaId 
                into All from al in All.DefaultIfEmpty()
            select new
            {
                a.Nome,
                al.Titulo
            }).ToList();

LAMBDA

var result = context.Artista
            .GroupJoin(context.Album, artista => artista.ArtistaId, album => album.ArtistaId,
                (artista, album) => new { Artista = artista, Album = album.DefaultIfEmpty() })
            .SelectMany(a => a.Album, (a, album) => new { 
                a.Artista.Nome, 
                album.Titulo 
            }).ToList();

7. Select com dois LEFT JOINS, GROUP BY e COUNT

T-SQL

SELECT DISTINCT a.Nome, 
              (SELECT COUNT(*) AS Album FROM Album WHERE ArtistaId = a.ArtistaId) AS Album, 
            	COUNT(f.FaixaId) AS Faixa 
        	FROM Artista a
LEFT JOIN Album al ON al.ArtistaId = a.ArtistaId
LEFT JOIN Faixa f ON f.AlbumId = al.AlbumId
GROUP BY a.Nome, a.ArtistaId;

LINQ

var result = (from a in context.Artista
        join al in context.Album on a.ArtistaId equals al.ArtistaId 
            into All1 from al in All1.DefaultIfEmpty()
        join f in context.Faixa on al.AlbumId equals f.AlbumId 
            into All2
        from f in All2.DefaultIfEmpty()
        group a by a into grouped
        let totalAlbuns = grouped.Key.Album.Count()
        let totalFaixas = grouped.Count(x => x.Album.Count > 0)
        select new
        {
            Artista = grouped.Key.Nome,
            Albuns = totalAlbuns,
            Faixas = totalFaixas
        }).ToList();

LAMBDA

var result = context.Artista
            .GroupJoin(context.Album, artista => artista.ArtistaId, album => album.ArtistaId,
                (artista, album) => album.Select(x => new { 
                                                    Artista = artista, 
                                                    Album = x 
                                                })
            .DefaultIfEmpty(new { 
                Artista = artista, 
                Album = (Albuns)null 
            }))
            .SelectMany(x => x)
            .GroupJoin(context.Faixa, 
album => album.Album.AlbumId, 
faixa => faixa.Album.AlbumId,
               	 (album, faixa) => faixa.Select(y => new { 
                                                Artista = album.Artista, 
                                                Album = album.Album, 
                                                Faixa = y 
                                            })
            .DefaultIfEmpty(new { 
                Artista = album.Artista, 
                Album = album.Album, 
                Faixa = (Faixas)null 
            }))
            .SelectMany(y => y)
            .GroupBy(grouped => new { grouped.Artista })
            .Select(g => new
            {
                Artista = g.Key.Artista.Nome,
                Albuns = g.Key.Artista.Album.Count(),
                Faixas = g.Count(x => x.Album.Faixa.Count > 0)
            }).ToList();

Como vocês puderam ver, a ideia desse artigo foi ser o mais direto ao ponto possível. Obviamente, é impossível cobrir todos os cenários possíveis de se fazer consultas T-SQL, então tentei colocar desde um exemplo simples, até um exemplo um pouco mais complexo.

Espero que tenham gostado e até a próxima!