Database Schema

Convertendo consultas T-SQL em LINQ

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

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

Nesse post vamos utilizar o Entity Framework como ORM e a linguagem LINQ to 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.

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

SELECT COM UM 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();

SELECT COM UM 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();

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

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

SELECT COM UM 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();

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 de ser o mais direto ao ponto possível. Obviamente, é impossivel 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.

Leave a Reply

Your email address will not be published. Required fields are marked *