Acesso a dados no C#, quando usar ADO.NET, Entity Framework ou Dapper e por que?

Marcio Nizzola
8 min readFeb 28, 2025

--

Acesso a dados no C#, quando usar ADO.NET, Entity Framework ou Dapper e por que?

Se você já participou de uma entrevista para desenvolvedor ou conduziu uma, sabe que uma pergunta clássica é: “Como você acessa dados no C#?”. Parece simples, né? Mas a verdade é que muitos candidatos travam na hora de explicar as diferenças entre ADO.NET, Entity Framework (EF) e Dapper. E, pior ainda, muitos não sabem quando e por que usar cada um desses “personagens” do mundo do acesso a dados.

Então, vamos descomplicar isso de uma vez por todas! Vou te ajudar a entender quando usar cada um e por que escolher um em detrimento dos outros. Afinal, na galáxia do desenvolvimento de software, a escolha certa pode ser a diferença entre um código elegante e um pesadelo de manutenção.

1. ADO.NET: O Mestre Yoda

O ADO.NET é o Yoda dos acessos a dados no C#. Ele existe desde os primórdios do .NET e é a base sobre a qual o Entity Framework e o Dapper foram construídos. Se você gosta de ter controle total sobre suas queries e conexões, o ADO.NET é o seu mestre.

Quando usar?

  • Quando você precisa de performance máxima. O ADO.NET é direto e não tem overhead (custo adicional) de ORM (Object-Relational Mapping).
  • Quando você está lidando com queries complexas ou procedures armazenadas que não se encaixam bem em um ORM.
  • Quando você quer controle total sobre a conexão, transações e execução de comandos SQL.

Exemplo:

using System;
using System.Data.SqlClient;

public class Usuario
{
public int Id { get; set; }
public string Nome { get; set; }
public string Email { get; set; }
public DateTime DataCadastro { get; set; }
}

public Usuario LerUsuario(int id)
{
Usuario usuario = null;
string connectionString = "SuaStringDeConexao";

using (SqlConnection connection = new SqlConnection(connectionString))
{
connection.Open();
string query = "SELECT Id, Nome, Email, DataCadastro FROM Usuario WHERE Id = @Id";

using (SqlCommand command = new SqlCommand(query, connection))
{
command.Parameters.AddWithValue("@Id", id);

using (SqlDataReader reader = command.ExecuteReader())
{
if (reader.Read())
{
usuario = new Usuario
{
Id = reader.GetInt32(0),
Nome = reader.GetString(1),
Email = reader.GetString(2),
DataCadastro = reader.GetDateTime(3)
};
}
}
}
}

return usuario;
}

O que está acontecendo?

  • Você abre uma conexão com o banco de dados.
  • Cria um comando SQL com parâmetros.
  • Executa o comando e mapeia manualmente os resultados para o objeto Usuario.

Por que usar?

  • Performance: Como não há camadas adicionais, ele é rápido.
  • Controle: Você escreve o SQL manualmente e gerencia tudo, desde a conexão até o fechamento.
  • Simplicidade: Para projetos pequenos ou scripts, o ADO.NET pode ser a opção mais direta.

Mas cuidado!

  • Código verboso: Você vai escrever mais código para fazer a mesma coisa que um ORM faria em poucas linhas.
  • Manutenção: Como o SQL está embutido no código, mudanças no banco podem exigir alterações manuais.

Eu particularmente não o utilizo mais, tenho resolvido com EF ou Dapper.

2. Entity Framework: O Luke Skywalker

Luke Skywalker

O Entity Framework (EF) é o Luke Skywalker dos ORMs. Ele é o herói que traz equilíbrio para a força, abstraindo o banco de dados em objetos C# e permitindo que você trabalhe com dados de forma mais “natural” para o desenvolvedor. Em vez de escrever SQL, você manipula objetos e deixa o EF cuidar do resto.

Quando usar?

  • Quando você quer produtividade. O EF permite criar e manter o banco de dados a partir do código (Code-First) ou gerar o código a partir do banco (Database-First).
  • Quando você está em um projeto com modelos de dados complexos e quer evitar escrever SQL manualmente.
  • Quando você precisa de migrations (controle de versão do banco de dados) e quer que isso seja feito automaticamente.

Exemplo:

using System;
using System.Linq;
using Microsoft.EntityFrameworkCore;

public class Usuario
{
public int Id { get; set; }
public string Nome { get; set; }
public string Email { get; set; }
public DateTime DataCadastro { get; set; }
}

public class MeuContexto : DbContext
{
public DbSet<Usuario> Usuarios { get; set; }

protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
{
optionsBuilder.UseSqlServer("SuaStringDeConexao");
}
}

public Usuario LerUsuario(int id)
{
using (var context = new MeuContexto())
{
return context.Usuarios.FirstOrDefault(u => u.Id == id);
}
}

O que está acontecendo?

  • O DbContext gerencia a conexão e o mapeamento.
  • Você usa LINQ para escrever consultas de forma intuitiva.
  • O EF gera o SQL automaticamente e mapeia os resultados para o objeto Usuario.

Por que usar?

  • Produtividade: Menos código para escrever e manter.
  • Abstração: Você trabalha com objetos, não com SQL.
  • Migrations: Facilita a evolução do banco de dados ao longo do tempo.

Mas cuidado!

  • Performance: O EF pode ser mais lento que o ADO.NET ou o Dapper, especialmente em queries complexas.
  • Curva de aprendizado: Dominar o EF exige entender conceitos como LINQ, tracking, lazy loading, etc.
  • Overhead: O EF adiciona uma camada de abstração que pode não ser necessária em projetos simples.

3. Dapper: O Han Solo

Han Solo

O Dapper é o Han Solo dos micro-ORMs. Ele é o mercenário que faz o trabalho sujo de forma rápida e eficiente. Criado pela galera do Stack Overflow, ele fica no meio-termo entre o ADO.NET e o Entity Framework: você ainda escreve SQL, mas o Dapper mapeia os resultados para objetos C# de forma automática. É como se fosse um ADO.NET turbinado.

Exemplo:

using System;
using Dapper;
using System.Data.SqlClient;

public class Usuario
{
public int Id { get; set; }
public string Nome { get; set; }
public string Email { get; set; }
public DateTime DataCadastro { get; set; }
}

public Usuario LerUsuario(int id)
{
string connectionString = "SuaStringDeConexao";

using (SqlConnection connection = new SqlConnection(connectionString))
{
connection.Open();
string query = "SELECT Id, Nome, Email, DataCadastro FROM Usuario WHERE Id = @Id";

return connection.QueryFirstOrDefault<Usuario>(query, new { Id = id });
}
}

O que está acontecendo?

  • Você escreve o SQL manualmente, mas o Dapper mapeia os resultados para o objeto Usuario.
  • O código é mais enxuto que o ADO.NET, mas ainda dá controle sobre o SQL.

Quando usar?

  • Quando você quer performance próxima do ADO.NET, mas com menos código.
  • Quando você precisa de controle sobre o SQL, mas não quer lidar com o mapeamento manual de resultados.
  • Quando tiver uma consulta que não vai usar o modelo de classes do Entity Framework.
  • Quando tiver uma execução de um código sql bastante complexo ou usar procedures, ele facilitará o seu trabalho e delegará para o Banco de Dados a complexidade da consulta, trazendo um modelo de dados pronto.
  • Quando você está em um projeto que não justifica a complexidade do EF, mas precisa de algo mais produtivo que o ADO.NET.

Por que usar?

  • Performance: Quase tão rápido quanto o ADO.NET, mas com menos código.
  • Simplicidade: Fácil de aprender e usar.
  • Controle: Você ainda escreve o SQL, mas o Dapper cuida do mapeamento.

Mas cuidado!

  • SQL manual: Você ainda precisa escrever SQL, o que pode ser um problema em projetos com modelos de dados muito complexos.
  • Menos recursos: Não tem migrations, tracking de entidades ou outras features avançadas do EF.

4. Combinando os Três: A Aliança Rebelde

Em alguns projetos, você pode precisar combinar os três “personagens” para obter o melhor de cada mundo. Por exemplo, você pode usar o Entity Framework para a maioria das operações, o Dapper para consultas complexas que precisam de performance, e o ADO.NET para operações críticas que exigem controle total.

Aqui está um exemplo de como você pode combinar os três em um mesmo programa:

using System;
using System.Data.SqlClient;
using Dapper;
using Microsoft.EntityFrameworkCore;

public class Usuario
{
public int Id { get; set; }
public string Nome { get; set; }
public string Email { get; set; }
public DateTime DataCadastro { get; set; }
}

public class MeuContexto : DbContext
{
public DbSet<Usuario> Usuarios { get; set; }

protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
{
optionsBuilder.UseSqlServer("SuaStringDeConexao");
}
}

public class UsuarioService
{
private string connectionString = "SuaStringDeConexao";

// Usando Entity Framework para operações comuns
public Usuario LerUsuarioEF(int id)
{
using (var context = new MeuContexto())
{
return context.Usuarios.FirstOrDefault(u => u.Id == id);
}
}

// Usando Dapper para consultas complexas
public Usuario LerUsuarioDapper(int id)
{
using (SqlConnection connection = new SqlConnection(connectionString))
{
connection.Open();
string query = "SELECT Id, Nome, Email, DataCadastro FROM Usuario WHERE Id = @Id";
return connection.QueryFirstOrDefault<Usuario>(query, new { Id = id });
}
}

// Usando ADO.NET para operações críticas
public Usuario LerUsuarioADONET(int id)
{
Usuario usuario = null;

using (SqlConnection connection = new SqlConnection(connectionString))
{
connection.Open();
string query = "SELECT Id, Nome, Email, DataCadastro FROM Usuario WHERE Id = @Id";

using (SqlCommand command = new SqlCommand(query, connection))
{
command.Parameters.AddWithValue("@Id", id);

using (SqlDataReader reader = command.ExecuteReader())
{
if (reader.Read())
{
usuario = new Usuario
{
Id = reader.GetInt32(0),
Nome = reader.GetString(1),
Email = reader.GetString(2),
DataCadastro = reader.GetDateTime(3)
};
}
}
}
}

return usuario;
}
}

O que está acontecendo?

  • Entity Framework: Usado para operações comuns, onde a produtividade é mais importante.
  • Dapper: Usado para consultas complexas que precisam de performance.
  • ADO.NET: Usado para operações críticas que exigem controle total.

Resumindo: Qual escolher?

  • ADO.NET (Yoda): Para projetos pequenos, scripts ou quando você precisa de controle total e performance máxima.
  • Entity Framework (Luke Skywalker): Para projetos pequenos, grandes, com modelos complexos, ou quando você quer produtividade e facilidade de manutenção.
  • Dapper (Han Solo): Quando você quer um equilíbrio entre controle e produtividade, com performance próxima do ADO.NET. Eu particularmente utilizo o Dapper juntamente com Entity Framework para consultas de maior performance ou consultas que não se encaixam na modelagem do Entity Framework.

IMPORTANTE: As últimas versões do .NET trouxeram muitas melhorias no Entity Framework, fazendo com que a sua performance esteja muito melhor que no passado, dispensando muitas vezes a necessidade de utilizar outras abordagens.

Conclusão: A Força Está com Você!

No fim do dia, a escolha entre ADO.NET, Entity Framework ou Dapper depende do contexto do seu projeto. Cada um tem seus prós e contras, e o segredo é saber quando usar cada um. E, claro, não tenha medo de misturar! Em um mesmo projeto, você pode usar o EF para a maioria das operações, o Dapper para queries críticas de performance e o ADO.NET para operações que exigem controle total.

E aí, qual é o seu preferido? Conte nos comentários!

Gostou do artigo? clique no ícone👏e me siga para ver as próximas publicações !! Quer ver mais conteúdos, acesse minhas redes através do Linktree: https://linktree.com/nizzola

--

--

Marcio Nizzola
Marcio Nizzola

Written by Marcio Nizzola

Microsoft MVP | Software Architect na CI&T | Prof. da Etec Itu | Membro Fundador da Comunidade Itu Developers.

Responses (1)