Ao desenvolver .NET e .NET Core orientados a banco de dados, independentemente do banco de dados que pretendemos implantar no final, muitas vezes desejaremos trabalhar com um mecanismo de banco de dados que seja leve e rápido, para executar testes rapidamente e acelerar o desenvolvimento . Aqui o SQLite é a escolha ideal.
Você pode usar o SQLite para obter acesso mais rápido aos dados e ocupar menos espaço. O banco de dados SQLite geralmente é armazenado como um único arquivo em disco, embora também possa funcionar como um banco de dados na memória. No entanto, ao contrário de um banco de dados na memória, o SQLite permite consultar dados sem ter que carregar todo o conjunto de dados na memória.
Dapper – o “micro ORM” leve e de código aberto sobre o qual escrevi com frequência – oferece suporte a muitos bancos de dados, incluindo SQL Server, MySQL, SQLite, SQL CE e Firebird. Ao usar o Dapper em suas aplicações, você pode simplificar o acesso aos dados e, ao mesmo tempo, garantir alto desempenho. Neste artigo, examinaremos como trabalhar com um banco de dados SQLite usando Dapper em aplicativos ASP.NET Core.
Para usar os exemplos de código fornecidos neste artigo, você deve ter o Visual Studio 2022 instalado em seu sistema. Se ainda não tiver uma cópia, você pode baixar o Visual Studio 2022 aqui.
Crie um projeto de API Web ASP.NET Core no Visual Studio 2022
Para criar um projeto de API Web ASP.NET Core no Visual Studio 2022, siga as etapas descritas abaixo.
- Inicie o IDE do Visual Studio 2022.
- Clique em “Criar novo projeto”.
- Na janela “Criar novo projeto”, selecione “API Web ASP.NET Core” na lista de modelos exibida.
- Clique em Avançar.
- Na janela “Configure seu novo projeto”, especifique o nome e o local do novo projeto. Opcionalmente, marque a caixa de seleção “Colocar solução e projeto no mesmo diretório”, dependendo de suas preferências.
- Clique em Avançar.
- Na janela “Informações adicionais” mostrada a seguir, selecione “.NET 8.0 (Long Term Support)” como a versão da estrutura. Certifique-se de que a caixa de seleção que diz “Usar controladores” esteja desmarcada, pois não usaremos controladores neste projeto.
- Em outra parte da janela “Informações adicionais”, deixe o “Tipo de autenticação” definido como “Nenhum” (o padrão) e certifique-se de que as caixas de seleção “Ativar suporte à API aberta”, “Configurar para HTTPS” e “Ativar Docker” permaneçam desmarcadas . Não usaremos nenhum desses recursos aqui.
- Clique em Criar.
Usaremos este projeto de API Web do ASP.NET Core para trabalhar com os exemplos de código fornecidos nas seções abaixo.
Instale os pacotes Dapper e SQLite NuGet
Neste exemplo, usaremos o Dapper para conectar e trabalhar com um banco de dados SQLite. Portanto, precisaremos instalar os pacotes Dapper e SQLite NuGet no projeto. Para fazer isso, selecione o projeto na janela Solution Explorer, clique com o botão direito e selecione “Gerenciar pacotes NuGet”.
Na janela NuGet Package Manager, procure os pacotes Dapper e Microsoft.Data.Sqlite e instale-os. Como alternativa, você pode instalar os pacotes por meio do console do NuGet Package Manager digitando o comando abaixo.
PM> Install-Package DapperPM> Install-Package Microsoft.Data.Sqlite
Crie um novo DbContext no EF Core
O DbContext é um componente integral do Entity Framework Core que representa uma sessão de conexão com o banco de dados. Crie uma nova classe chamada CustomDbContext estendendo a classe DbContext do EF Core e insira o código a seguir nela.
public class CustomDbContext : DbContext { protected override void OnConfiguring (DbContextOptionsBuilder optionsBuilder) { optionsBuilder.UseInMemoryDatabase(databaseName: "IDGSampleDb"); } public DbSet<User> Users { get; set; } }
Crie um banco de dados SQLite
Para criar um novo banco de dados SQLite, tudo que você precisa fazer é criar uma nova instância da classe SqliteConnection e passar seu nome para o banco de dados como parâmetro para seu construtor conforme mostrado abaixo.
string databaseName = "demo.db"; _ = new SqliteConnection("Data Source=" + databaseName);
Observe o uso do literal _ (sublinhado) no lado esquerdo do operador de atribuição. Isso também é conhecido como descarte e é usado para informar ao compilador que mesmo que o método retorne um valor, você não deseja usá-lo.
Depois que o banco de dados SQLite for criado, você poderá usar o seguinte trecho de código para criar uma tabela no banco de dados.
sqliteConnection.Execute( @"create table Author ( ID integer identity primary key, FirstName varchar(50) not null, LastName varchar(50) not null, Address nvarchar(100) not null )");
A Figura 1 mostra o banco de dados e sua tabela criada no DBBrowser do SQLiteStudio.
A classe a seguir chamada CustomDataContext contém o código completo para criar um banco de dados SQLite e uma tabela dentro dele.
using Dapper; using Microsoft.Data.Sqlite; public class CustomDataContext { private SqliteConnection CreateDatabaseConnection(string databaseName) { return new SqliteConnection("Data Source=" + databaseName); } public async Task<SqliteConnection> CreateDatabase(string databaseName) { using (var sqliteConnection = CreateDatabaseConnection(databaseName)) { await sqliteConnection.ExecuteAsync( @"CREATE TABLE IF NOT EXISTS Author ( Id INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT, FirstName TEXT NOT NULL, LastName TEXT NOT NULL, Address TEXT NOT NULL )"); return sqliteConnection; } } }
Você pode chamar o método CreateDatabase da classe CustomDataContext e passar o nome do banco de dados SQLite que deseja criar usando o seguinte trecho de código.
await new CustomDataContext().CreateDatabase("demo.db");
Crie um repositório de autor e uma interface no ASP.NET Core
Vamos agora criar um repositório, denominado Author, que compreenderá dois tipos: a interface IAuthorRepository e a classe AuthorRepository. Cada um desses tipos usará a classe Author como modelo. O código-fonte da classe de modelo Autor é fornecido abaixo.
public class Author { public int Id { get; set; } public string FirstName { get; set; } public string LastName { get; set; } public string Address { get; set; } }
Em seguida, crie uma nova interface chamada IAuthorRepository e substitua o código gerado pela listagem de código a seguir.
public interface IAuthorRepository { Task<IEnumerable<Author>> GetAll(); Task<Author> GetById(int id); Task Create(Author Author); Task Update(Author Author); Task Delete(int id); }
A classe AuthorRepository implementará cada um dos métodos da interface IAuthorRepository conforme mostrado abaixo.
public class AuthorRepository : IAuthorRepository { private CustomDataContext _context; private string databaseName = "demo.db"; public AuthorRepository(CustomDataContext context) { _context = context; } public async Task<IEnumerable<Author>> GetAll() { using var connection = await _context.CreateDatabase(databaseName); var sql = "SELECT * FROM Author"; return await connection.QueryAsync<Author>(sql); } public async Task<Author> GetById(int id) { using var sqliteConnection = await _context.CreateDatabase(databaseName); string sql = "SELECT * FROM Author WHERE Id = @id"; return await sqliteConnection. QueryFirstOrDefaultAsync<Author>(sql, new { id }); } public async Task Create(Author Author) { using var sqliteConnection = await _context.CreateDatabase(databaseName); string sql = "INSERT INTO Author (FirstName, LastName, Address) " + "VALUES (@FirstName, @LastName, @Address)"; await sqliteConnection.ExecuteAsync(sql, Author); } public async Task Update(Author Author) { using var sqliteConnection = await _context.CreateDatabase(databaseName); string sql = "UPDATE Author SET FirstName = @FirstName, " + "LastName = @LastName, Address = @Address WHERE Id = @Id"; await sqliteConnection.ExecuteAsync(sql, Author); } public async Task Delete(int id) { using var sqliteConnection = await _context.CreateDatabase(databaseName); string sql = "DELETE FROM Author WHERE Id = @id"; await sqliteConnection.ExecuteAsync(sql, new { id }); } }
Registrar dependências no ASP.NET Core
Em seguida, você deve registrar as dependências no pipeline de processamento de solicitações para poder usar a injeção de dependência para criar essas instâncias sempre que precisar delas. O código a seguir mostra como você pode registrar instâncias de CustomDataContext e AuthorRepository no arquivo Program.cs.
builder.Services.AddScoped<CustomDataContext>(); builder.Services.AddScoped<IAuthorRepository, AuthorRepository>();
Crie pontos de extremidade HTTP no ASP.NET Core
Agora você pode usar o código a seguir para criar os endpoints para executar operações CRUD (criar, ler, atualizar, excluir) no banco de dados.
app.MapGet("/authors/{id}", async (int id, IAuthorRepository repository) => await repository.GetById(id)); app.MapPut("/authors", async (Author author, IAuthorRepository repository) => await repository.Update(author)); app.MapPost("/authors", async (Author author, IAuthorRepository repository) => await repository.Create(author)); app.MapDelete("/authors/{id}", async (int id, IAuthorRepository repository) => await repository.Delete(id));
E isso é tudo que você precisa fazer. Agora você pode invocar os endpoints conforme necessário. Por exemplo, você pode invocar o endpoint HTTP Get /authors para exibir todos os registros do autor no navegador da web, conforme mostrado na Figura 2.
SQLite é leve, rápido e fácil de usar, mas também tem algumas desvantagens. Não é escalável nem adequado para armazenar grandes volumes de dados. Para armazenamento de dados em grande escala e aplicativos de alto tráfego que atendem a muitos usuários simultâneos, você deve considerar um banco de dados cliente/servidor, como SQL Server ou MySQL. Mas o SQLite brilha como companheiro de desenvolvimento – e para uso em desktop, dispositivos móveis, IoT e aplicativos incorporados.