C# - Dapper Tutorial com VS Code


 Hoje vou apresentar um tutorial que mostra como usar o Dapper de forma simples e direta para programação com banco de dados. 

Neste artigo vou usar o ambiente do Visual Studio Code e o banco de dados SQL Server nos exemplos apresentados.

Embora não seja um quesito obrigatório eu vou usar no Visual Studio a extensão SQL Server (mssql) para poder interagir com o banco de dados e as tabelas no ambiente do Visual Studio Code:

Com esta extensão podemos fazer a conexão com o SQL Server Local, executar scripts, visualizar os banco de dados, consultar tabelas, temos ainda opções de extensão personalizáveis, incluindo atalhos de comando e muito mais.

O que é o Dapper ?

O Dapper é um mapeador de objetos simples para a plataforma  .NET que podemos usar para mapear um modelo de domínio orientado a objetos para um banco de dados relacional tradicional. Os objetivos de Dapper são simplicidade de código e desempenho.

O Dapper não tem detalhes de implementação específicos do banco de dados, ele funciona em todos os provedores .NET ADO, incluindo SQLite, SQL CE, Firebird, Oracle, MySQL, PostgreSQL e SQL Server.

Para usar o Dapper em um projeto na plataforma .NET basta incluir o pacote nuget Dapperdotnet add package dapper

recursos usados:

Preparando o ambiente e criando a fonte de dados

Vamos iniciar acessando a extensão SQL Server no VS Code e fazendo a conexão com a instância local do SQL Server.

A seguir vamos abrir essa instância no VS Code e criar o banco de dados Concessionaria emitindo o comando:

CREATE DATABASE  Concessionaria

Com o banco criado agora vamos criar a tabela Veiculos neste banco e incluir alguns dados conforme o script SQL abaixo:

CREATE TABLE Veiculos (
Id INT identity(1,1) NOT NULL PRIMARY KEY,
Modelo VARCHAR(255) NOT NULL,
Ano INT,
Preco INT
)

INSERT INTO Veiculos(Modelo,Ano,Preco) VALUES('Audi',2005,52642);
INSERT INTO Veiculos(Modelo,Ano,Preco) VALUES('Mercedes',2008,47127);
INSERT INTO Veiculos(Modelo,Ano,Preco) VALUES('Volvo',2010,12200);
INSERT INTO Veiculos(Modelo,Ano,Preco) VALUES('Citroen',2015,22102);
INSERT INTO Veiculos(Modelo,Ano,Preco) VALUES('Volkswagen',2018,42500);
INSERT INTO Veiculos(Modelo,Ano,Preco) VALUES('Ford',2019,32570);

Usando a extensão teremos:

Após isso podemos consultar a tabela criada com os dados incluídos:

Vamos usar esse banco dados e esta tabela em nosso tutorial Dapper.

Criando a solução e projeto

Vamos abrir uma janela de comandos (estou usando o PowerShell) e criar a pasta projetos e dentro desta pasta vamos criar a pasta dapper.

A seguir entrando na pasta \projetos\dapper vamos criar :

1- Uma solução chamada DapperTutorial

dotnet new sln -n DapperTutorial

2- Criar um projeto do tipo Console chamado DapperCommands

dotnet new console -n DapperCommands

3- A seguir vamos incluir o projeto criado na solução criada:

dotnet sln DapperTutorial.sln add DapperCommands\DapperCommands.csproj

Vamos entrar na pasta do projeto DapperCommands e abrir o projeto criado no Visual Studio Code digitando : code .

Com o projeto aberto no VS Code vamos abrir uma janela usando a opção Terminal e incluir os seguintes pacotes no projeto:

Digitando o comando : dotnet add package <nome_do_pacote>

Ao final teremos no arquivo de projeto as referências indicadas conforme figura abaixo:

Criando o arquivo de configuração e definindo a string de conexão e a classe Veiculo

Vamos incluir na raiz do projeto um arquivo appsettings.json e incluir neste arquivo a string de conexão para acessar o banco de dados Concessionaria:

{
 "ConnectionStrings": {
   "DefaultConnection": "Data Source=desktop-bhp8771\\sqlexpress;Initial Catalog=Concessionaria;
Integrated Security=True"
  }
}

Para concluir vamos criar uma classe chamada Veiculo que será mapeada para a tabela Veiculos:

public class Veiculo
{
        public int Id { get; set; }
        public string Modelo { get; set; }
        public int Ano { get; set; }
        public int Preco { get; set; }

        public override string ToString()
        {
             return $"{Id} \t{Modelo} \t{Ano} \t{Preco}";
        }

}

Lendo o arquivo de configuração e definindo as opções de comandos

A seguir vamos definir no método Main da classe Program o código para ler o arquivo appsettings.json e obter o valor da string de conexão e apresentar as opções dos comandos que iremos tratar neste tutorial:

using System;
using System.IO;
using Microsoft.Extensions.Configuration;

namespace DapperCommands
{
    class Program
    {
        public static IConfiguration Configuration { get; set; }
        static void Main(string[] args)
        {
            var builder = new ConfigurationBuilder()
                .SetBasePath(Directory.GetCurrentDirectory())
                    .AddJsonFile("appsettings.json", optional: false);

            Configuration = builder.Build();

            string conSql = Configuration["ConnectionStrings:DefaultConnection"];

            Console.WriteLine("## Dapper Tutorial ##\n");
            Console.WriteLine("\te - ExecuteScalar");
            Console.WriteLine("\tq - Query");
            Console.WriteLine("\tx - Execute");
            Console.WriteLine("\tp - QueryParametrized");
            Console.WriteLine("\td - Delete");
            Console.WriteLine("\ty - DynamicParameters\n");
            Console.Write("Sua opção (e,q,x,p,d,y) ? \n");
            switch (Console.ReadLine())
            {
                case "e":
                    ExecuteScalar(conSql);
                    break;
                case "q":
                    Query(conSql);
                    break;
                case "x":
                    Execute(conSql);
                    break;
                case "p":
                    QueryParametrized(conSql);
                    break;
                case "d":
                    Delete(conSql);
                    break;
                case "y":
                    DynamicParameters(conSql);
                    break;
            }
            Console.ReadKey();
        }
    }
}

Com isso já podemos criar os métodos onde vamos usar os comandos do Dapper.

Criando os métodos e usando os comandos Dapper

1- ExecuteScalar

O método ExecuteScalar() executa uma consulta que seleciona um único valor.
O exemplo recupera a versão do banco de dados SQL Server.
O método ExecuteScalar() executa a consulta SELECT @@ VERSION, que retorna um único valor: a versão do SQL Server.

 private static void ExecuteScalar(string conSql)
 {
       using var con = new SqlConnection(conSql);
       con.Open();
       var version = con.ExecuteScalar<string>("SELECT @@VERSION");
       Console.WriteLine(version);
 }

Para executar o projeto digite em uma janela do Terminal: dotnet run

Resultado:

2- Query

O método Query() executa uma consulta e mapeia para uma lista de objetos dinâmicos.
NO exemplo estamos recuperando todas as linhas da tabela Veiculos.
O método Query() executa a instrução SELECT * FROM Veiculos e retorna uma lista de objetos.

private static void Query(string conSql)
{
     using var con = new SqlConnection(conSql);
     con.Open();

     var veiculos = con.Query<Veiculo>("SELECT * FROM Veiculos").ToList();

      veiculos.ForEach(veiculo => Console.WriteLine(veiculo));
}

Resultado:

3- Execute

O método Execute() executa uma consulta SQL
O exemplo a seguir atualiza o preço de um único veículo e retorna o número de linhas afetadas.
A instrução UPDATE atualiza o preço de um veículo.

private static void Execute(string conSql)
{
    using var con = new SqlConnection(conSql);
    con.Open();

   int numeroLinhasAfetads = con.Execute("UPDATE dbo.[Veiculos] SET [preco] = 77000 WHERE [id] = 1");

   Console.WriteLine($"O comando 'UPDATE' afetou {numeroLinhasAfetads} registros");
}

Resultado:

Abrindo a tabela Veiculos e consultando os dados confirmarmos o resultado:

4- Parametrized Query

As consultas parametrizadas aumentam a segurança e o desempenho. Quando escrevemos consultas parametrizadas, usamos marcadores em vez de escrever diretamente os valores nas consultas.

O exemplo a seguir seleciona uma linha específica da tabela Veiculos.

O comando QueryFirst() retorna o primeiro resultado da consulta SQL, e o @id é um espaço reservado a ser preenchido. O segundo argumento é o parâmetro para preencher o espaço reservado.

 private static void QueryParametrized(string conSql)
 {
            using var con = new SqlConnection(conSql);
            con.Open();

            var veiculo = con.QueryFirst<Veiculo>("SELECT * FROM Veiculos WHERE id=@id",new { id = 3 });        

            Console.WriteLine(veiculo);
     }

Resultado:

5- Deletar um linha

O exemplo a seguir executa uma consulta que deleta uma linha ou registro da tabela Veiculos:

 private static void QueryParametrized(string conSql)
 {
            using var con = new SqlConnection(conSql);
            con.Open();

            int linhasDeletadas = con.Execute(@"DELETE FROM [Veiculos] WHERE Id = @Id", new { Id = 6 });

            if (linhasDeletadas > 0)
            {
                Console.WriteLine("O veículo foi deletado...");
            }
  }

Resultado:

Consultando a tabela Veiculos confirmamos a exclusão do registro 6:

6- DynamicParameters

O recurso DynamicParameters é um conjunto de parâmetros que podem ser passados para os métodos Query e Execute.
No exemplo estamos inserindo uma nova linha na tabela de Veiculos onde fornecemos dinamicamente os valores dos parâmetros e seus tipos.
Os parâmetros dinâmicos são passados como o segundo argumento do método Execute().

 private static void DynamicParameters(string conSql)
 {
            using var con = new SqlConnection(conSql);
            con.Open();

            var query = "INSERT INTO Veiculos(modelo,ano,preco) VALUES(@modelo,@ano, @preco)";

            var dp = new DynamicParameters();

            dp.Add("@modelo", "BMW", DbType.AnsiString, ParameterDirection.Input, 255);
            dp.Add("@ano", 2020);
            dp.Add("@preco", 36600);

            int resultado = con.Execute(query, dp);

            if (resultado > 0)
            {
                Console.WriteLine("Registro incluído na tabela");
            }
 }

Resultado:

Abrindo a tabela Veiculos vemos o novo registro incluído:

Pegue o código do projeto aqui: dapper_tutorial.zip

"Bom é ter esperança, e aguardar em silêncio a salvação do Senhor."
Lamentações 3:26

Referências:


José Carlos Macoratti