C#  - CRUD básico no SQLite com VS 2015


Neste artigo vou mostrar como realizar um CRUD básico usando o banco de dados SQLite em uma aplicação Windows forms com o VS Community 2015 e a linguagem C#.

O SQLite é um banco de dados free de domínio público e ao contrário do SQL Server , Oracle ou outro banco de dados comercial ele não é um programa independente e não possui um servidor. Ele é uma pequena library escrita em C que outras aplicações podem chamar.

Um banco de dados SQLite é um apenas um arquivo único onde as tabelas os dados, triggers, chaves primárias e estrangeiras estão todas contidas. A sua aplicação lê e escreve no banco de dados pela chamada do SQLite. Quando você realizar um SELECT ou UPDATE o SQLite lê e escreve para este arquivo.

Se você efetuar atualizações em uma transação SQL o SQLite verifica se você possui acesso exclusivo ao arquivo e você pode fazer uma cópia de segurança apenas copiando o arquivo do SQLite.

Em resumo você pode usar o SQLite como qualquer outro banco de dados mas por trás dos panos você estará usando uma pequena livraria de código a qual esta armazenando seus dados em um arquivo.

Um detalhe, o SQLite esta sob domínio público, e assim qualquer um pode copiar, modificar, publicar, usar, compilar, vender ou distribuir o código original do SQLite para propósitos comerciais ou não comerciais. Não há restrição alguma no SQLite.

O SQLite suporta a maior parte dos recursos da linguagem SQL padrão com algumas limitações. Como o SQLite escreve e lê para um arquivo em um drive as únicas permissões disponíveis são as permissões de leitura e escrita para o próprio arquivo então não há como usar os comandos GRANT e REVOKE. Para uma relação das limitações visite este link: http://www.sqlite.org/omitted.html

O SQLite dá suporte a transações ACID (Atomic, Consistent, Isolated and Durable). O que significa que uma transação no SQLite irá ocorrer completamente ou não.

Por tudo isso creio que vale a pena considerar a utilização do SQLite quando o cenário for favorável a sua utilização mas lembre-se que ele possui limitações e que isso nem sempre será possível.

O tamanho do SQLite configurado é no máximo de 300 KB por isso ele é indicado para pequenas aplicações (portáveis) especialmente aplicações que não precisam rodar on-line onde os dados são armazenados em um arquivo local e o banco de dados trabalha sem uma conexão com internet.

Você pode obter mais informações e fazer o download do SQLite na página oficial: http://www.sqlite.org/index.html

Dica: Usando o Nuget você pode facilitar o seu trabalho e baixar o pacote com o connector no seu projeto.  (Veja este artigo  .NET - Apresentando o Nuget - Macoratti.net )

Neste artigo eu vou mostrar como realizar um CRUD básico usando o SQLite e a linguagem C# fazendo algumas considerações sobre como usar a ADO .NET.

Recursos usados:

Nota: Baixe e use a versão Community 2015 do VS ela é grátis e é equivalente a versão Professional.

Criando o banco de dados via SQLite Administrador

Existem muitas ferramentas para o gerenciamento e a criação de banco de dados no SQLite, no link abaixo você pode encontrar muitas dessas ferramentas: http://www.sqlite.org/cvstrac/wiki?p=ManagementTools

Eu vou usar o SQLite Administrator que você pode baixar aqui: http://sqliteadmin.orbmu2k.de/;

Após fazer o download do SQLite, instalar, e, em seguida instalar o provedor para ADO .NET, instale por último o SQL Administrator.

Após a instalação ao abrir o programa e selecionar o idioma português você verá a seguinte tela:

Para criar o banco de dados basta selecionar no menu Database a opção Novo e informar a localização e nome do arquivo.

Para o exemplo deste artigo eu vou criar o banco de dados Cadastro na pasta c:\dados\SQLite; (Seria criado o arquivo Cadastro.s3db )

Para criar uma tabela clique no item Tabelas e selecione Criar Tabela;

Informe o nome da tabela e clique no botão adicionar campo para incluir os campos informando o tipo de do campo e o valor padrão;

Eu vou criar uma tabela chamada Alunos com a seguinte estrutura:

Podemos inclusive obter a instrução SQL para gerar a tabela via script:

Para incluir dados na tabela podemos usar a janela de consulta SQL informando a instrução SQL :

Para editar os dados temos a janela Edita Dados:

Dessa forma já temos o nosso banco de dados e tabela criados no SQLite e prontos para serem usados na nossa aplicação C#.

Criando a solução no VS 2015 Community

Abra o Visual Studio Community 2015 e clique em New Project;

Selecione Other Project Types -> Visual Studio Solution e Blank Solution

Informe o nome CRUD_SQLite e clique no botão OK.

Informe o nome CRUD_SQLite  e clique no botão OK.  Com isso criamos a solução.

Agora que temos a solução criada vamos incluir um projeto do tipo Windows Forms onde eu irei mostrar como fazer o CRUD usando uma abordagem sem camadas.

Nessa abordagem irei incluir todo o código ADO .NET no formulário Windows Forms para mostrar uma maneira não muito aderente, mas muito usada, de acessar e persistir informações em banco de dados.

A seguir irei mostrar a abordagem em camadas, que é mais robusta e a mais indicada.

Incluindo o projeto Windows para a abordagem sem camadas

Vamos agora incluir o projeto Windows Forms para realizar o CRUD.

No menu File clique em Add -> New Project;

Selecione o template Windows -> Windows Forms Application e informe o nome : CRUD_SQLite.SemCamadas;

Clique em OK.

Instalando o pacote do SQLite via Nuget

No menu Tools clique em Nuget Packet Manager e a seguir em Manage Nuget Packages for Solution;

Clique na guia Browse, informe SQLite e a seguir escolha o pacote do SQLite marcando o projeto para o qual deseja instalar e clique em Install;

Ao final você verá em References na janela Solution Explorer os pacotes referenciados no projeto.

Criando a classe de domínio Aluno

Vamos criar uma classe chamada Aluno que irá representar o nosso domínio e será usada para armazenar e transferir informações de um aluno.

Essa classe terá 4 propriedades espelhando a tabela alunos que foi criada no banco de dados Cadastro.

No menu Project clique em Add Class e informe o nome Aluno. A seguir inclua o código abaixo nesta classe:

    public class Aluno
    {
        public int Id { get; set; }
        public string nome { get; set; }
        public string email { get; set; }
        public int idade { get; set; }
    }

 

Essa classe irá nos  ajudar quando formos definir as operações CRUD pois poderemos passar o objeto aluno e não valores primitivos que representariam os valores das informações dos alunos.

Definindo a interface com o usuário

Agora vamos definir a interface no formulário form1.cs incluindo a partir da ToolBox os seguintes controles:

Disponha os controles conforme o leiaute da figura abaixo:

Para poder incluir e alterar dados vamos precisar de um formulário que exiba os dados a serem alterados ou um formulário apenas para o usuário informar os novos dados.

No menu Project clique em Add Windows Forms e aceite o nome padrão Form2.cs.

A seguir inclua 3 Labels , 3 TextBox (txtNome, txtEmail e txtIdade) e 2 Buttons (btnSalvar e btnSair) conforme o leiaute abaixo:

Agora podemos implementar o acesso e a persistência das informações usando ADO .NET para o SQLite.

Existem diversas formas de acessar e persistir dados mas em geral a sequência usada é a seguinte:

Seguindo este fluxo, podemos usar o código abaixo par carregar informações e exibir no DataGridView - dgvAlunos :

       private void CarregaDados()
        {
            DataTable dt = new DataTable();
            SQLiteConnection conn = null;
            String sql = "select * from Alunos";
            String strConn = @"Data Source=C:\dados\SQLite\Cadastro.s3db";
            try
            {
                conn = new SQLiteConnection(strConn);
                SQLiteDataAdapter da = new SQLiteDataAdapter(sql, strConn);
                da.Fill(dt);
                dgvAlunos.DataSource = dt.DefaultView;
            }
            catch (Exception ex)
            {
                MessageBox.Show("Erro :" + ex.Message);
            }
            finally
            {
                if (conn.State == ConnectionState.Open)
                {
                    conn.Close();
                }
            }
        }

O código acima funciona, mas possui muitas responsabilidades e pode ser melhorado. Destaques negativos do código acima:

Vejamos a seguir outras duas opções de código que obtém o mesmo resultado mas que apresentam melhorias:

        public DataTable LeDados1<T>(string query) where T : IDbConnection, new()
        {
            using (var conn = new T())
            {
                using (var cmd = conn.CreateCommand())
                {
                    cmd.CommandText = query;
                    cmd.Connection.ConnectionString = _connectionString;
                    cmd.Connection.Open();
                    var table = new DataTable();
                    table.Load(cmd.ExecuteReader());
                    return table;
                }
            }
        }

 

       public DataTable LeDados2<S, T>(string query) where S : IDbConnection, new()
                                           where T : IDbDataAdapter, IDisposable, new()
        {
            using (var conn = new S())
            {
                using (var da = new T())
                {
                    using (da.SelectCommand = conn.CreateCommand())
                    {
                        da.SelectCommand.CommandText = query;
                        da.SelectCommand.Connection.ConnectionString = _connectionString;
                        DataSet ds = new DataSet(); 
                        da.Fill(ds);
                        return ds.Tables[0];
                    }
                }
            }
        }

Esta abordagem possui as seguintes vantagens:

Para chamar o método LeDados1() usamos :   dgvAlunos.DataSource = LeDados1<SQLiteConnection>("Select * from Alunos");

Para chamar o método LeDados2() usamos :   dgvAlunos.DataSource = LeDados2<SQLiteConnection, SQLiteDataAdapter>("Select * from Alunos");

O  resultado final irá exibir todos os registros da tabela Alunos no DataGridView.

Dessa forma quando for implementar sua camada de acesso a dados considere usar Generics para obter uma maior flexibilidade.

Nota: Devemos atentar também para o fato de que usar um comando SQL que retorna todos os dados de uma tabela não é uma boa prática.

Implementando o CRUD

Para realizar a manutenção de dados geralmente usamos as instruções SQL : INSERT INTO, UPDATE, DELETE FROM, SELECT

Existem três abordagens que podemos usar para realizar esta tarefa:

Essa instrução sql seleciona todos os dados da tabela alunos usando o critério da id que é fornecido e obtido na caixa de texto txtId;
Essa abordagem é muito usada
mas não deve ser usada pois abre uma porta para que seja feita um ataque conhecido como injeção SQL, onde um código malicioso pode ser injetado no seu código.

Para evitar esse tipo de problema devemos usar parâmetros, pois qualquer informação colocada como parâmetro será tratada como um campo de dados, e não como parte da instrução SQL tornando assim sua aplicação mais segura.

Na construção de uma consulta parametrizada devemos seguir 3 etapas:

Os procedimentos armazenados são como pequenos programas em miniaturas que ficam 'dentro' do banco de dados prontos para serem usados. Geralmente uma stored procedure(sp) consiste em instruções SQL que realizam tarefas como selecionar , inclui , alterar e excluir dados.

Na próxima parte do artigo iremos iniciar a implementação do CRUD usando ADO .NET.

"Porque estas nações, que hás de possuir, ouvem os prognosticadores e os adivinhadores; porém a ti o Senhor teu Deus não permitiu tal coisa."
Deuteronômio 18:14

Veja os Destaques e novidades do SUPER DVD Visual Basic (sempre atualizado) : clique e confira !

Quer migrar para o VB .NET ?

Quer aprender C# ??

Quer aprender os conceitos da Programação Orientada a objetos ?

Quer aprender o gerar relatórios com o ReportViewer no VS 2013 ?

Quer aprender a criar aplicações Web Dinâmicas usando a ASP .NET MVC 5 ?

 

  Gostou ?   Compartilhe no Facebook   Compartilhe no Twitter

 

Referências:


José Carlos Macoratti