Utilizando C# com MongoDB

Criando uma aplicação em C# com o MongoDB

Nós desenvolvedores de software estamos acostumados a escrever além do código da nossa linguagem de programação preferida e/ou de trabalho, escrever também código SQL para procedures, views, criação de tabelas, etc. Mas… E se o seu banco não precisasse de código SQL? Se ele não tivesse procedures, views, triggers ou quaisquer outros comandos SQL? Difícil de imaginar, não? Pois é o que veremos na prática neste artigo.

É aí que entra o MongoDB (não riam do nome). Ele é um banco de dados diferente, pois não é um banco relacional como o SQL Server, muito menos um banco “orientado a tabelas” como o Google Bigtable. Ele é orientado a documentos, é um banco de dados do modelo chamado “Binary JSON”, ou simplesmente BSON.

O BSON é uma serialização binária de documentos baseados em JSON, e assim como o JSON, suporta a inclusão de objetos e vetores dentro de outros objetos e vetores.

Apesar de BSON significar “Binary JSON”, o formato contém extensões para representar tipos de dados não inclusos na especificação do JSON. Por instância, o BSON suporta formatos como BinData e Date(data). Comparado com o JSON, o BSON é igualmente eficiente em armazenamento e velocidade de busca. Isso ocorre em virtude de os documentos grandes deste formato possuírem um prefixo com o tamanho do campo para facilitar a busca.

De início, o BSON parece com o BLOB (Binary Large OBjects), mas existe uma importante diferença: O MongoDB pode “adentrar” objetos BSON, mesmo se estiverem aninhados. Dentre outras coisas, isto permite que uma base de dados MongoDB crie índices e busque objetos através de query expression tanto nos objetos de nível maior, quanto nas chaves aninhadas BSON.

Quem já trabalhou com camadas de mapeamento objeto-relacional (ORM, Object-Relational Mapping – na sigla em inglês) não terá grandes dificuldades em utilizar o MongoDB.

Os SGBDs BSON ainda são uma novidade para a maioria dos desenvolvedores, mas como na internet nada fica anônimo por muito tempo, já temos drivers para conexão com o MongoDB em várias linguagens, inclusive em C#.

Instalação

A instalação do MongoDB é extremamente simples: Inicialmente, baixe a versão Windows dele em http://www.mongodb.org/display/DOCS/Downloads (além de Windows x32/x64 existem também versões para outros sistemas operacionais). Crie um diretório C:\data\db e extraia os arquivos para dentro deste diretório, que é o padrão do MongoDB (mas que pode ser alterado).

Feito isso, abra uma janela de prompt e navegue até a pasta C:\data\db\bin e execute o mongod.exe, após isso abra outro prompt, navegue até a mesma pasta e execute o mongo.exe (repare na diferença dos nomes dos executáveis, para não errar).

MongodEXE
Tela após a execução do primeiro executável – mongod.exe

Agora, na segunda janela aberta (aonde você executou o mongo.exe), execute os seguintes comandos:

db.foo.save( { a : 1 } ) e pressione enter;

db.foo.findOne() e pressione enter;

Tela após a execução dos comandos acima.

O que acabamos de fazer foi salvar o índice chave-valor a: 1 no banco de dados foo, e em seguida mandamos fazer uma busca de um único elemento, mas sem parâmetros (o equivalente a um SELECT TOP 1 * FROM FOO, em SQL). Pronto, seu MongoDB está configurado e pronto para usar!

Agora, precisamos baixar o driver de conexão do .NET com o MongoDB, disponível em http://github.com/samus/mongodb-csharp . Salve onde achar melhor, extraia e pronto, podemos começar!

Abra o Visual Studio 2008 e crie uma aplicação web (File>>New>>Project>>Visual C#>> ASP.NET Web Application) e dê a ela o nome de MongoApp. Esta aplicação simples nada mais fará do que um CRUD básico em uma tela de cadastro de produtos.

Adicione ao projeto uma referência ao driver. Para isso, clique em com o botão direito em References>>Add reference, clique na aba Browse, navegue até a pasta onde você extraiu o projeto samus mongodb, vá até a pasta \MongoDBDriver\bin\Release e adicione a DLL do driver de conexão ao seu projeto. Podemos começar a tela, que ficará mais ou menos assim:

Tela de CRUD da aplicação

Feito isso, é a hora de irmos ao código C# que irá executar as operações de CRUD quando clicarmos nos botões da nossa página ASP.NET:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using MongoDB.Driver;
using MongoDB.Driver.Bson;
using MongoDB.Driver.IO;
namespace MongoApp
{
    public partial class _Default : System.Web.UI.Page
    {
        protected void Page_Load(object sender, EventArgs e)
        {
            txtNome.Text = "";
            txtQtdd.Text = "";
            txtDataValidade.Text = "";
            txtValor.Text = "";
        }

        protected void btnSalvar_Click(object sender, EventArgs e)
        {
            //Objeto de conexão com o banco
            var mongo = new Mongo();

            /*Esse é o principal objeto da aplicação,
             * seria o "objeto de negócio",
             * do tipo par-valor(dicionário)
             */
            var produto = new Document();

            mongo.Connect();

            /*Variável do tipo Database,
             * executa funções de conexão
             */
            var db = mongo.getDB("BancoDeDados");

            /*Pegando a coleção, que seria o equivalente
             *a uma tabela em SQL
             */
            var produtosColecao = db.GetCollection("Produtos");

            //Definindo os valores das propriedades.
            produto["valor"] = txtValor.Text;
            produto["nome"] = txtNome.Text;
            produto["validade"] = txtDataValidade.Text;
            produto["quantidade"] = txtQtdd.Text;

            try
            {
                produtosColecao.Insert(produto);
            }
            catch (Exception ex)
            {

                Response.Write("

 Data:" + ex.Data + "
Message: " +
                    ex.Message + "
InnerException:" + ex.InnerException +
                               "
 Stacktrace:" + ex.StackTrace +"

");
            }
        }

        protected void btnExcluir_Click(object sender, EventArgs e)
        {
            //Objeto de conexão com o banco
            var mongo = new Mongo();

            /*Esse é o principal objeto da aplicação,
             * seria o "objeto de negócio",
             * do tipo par-valor(dicionário)
             */
            var produto = new Document();

            mongo.Connect();

            /*Variável do tipo Database,
             * executa funções de conexão
             */
            var db = mongo.getDB("BancoDeDados");

            /*Pegando a coleção, que seria o equivalente
             *a uma tabela em SQL
             */
            var produtosColecao = db.GetCollection("Produtos");

            //Definindo os valores das propriedades.
            produto["valor"] = txtValor.Text;
            produto["nome"] = txtNome.Text;
            produto["validade"] = txtDataValidade.Text;
            produto["quantidade"] = txtQtdd.Text;

            try
            {
                produtosColecao.Delete(produto);
            }
            catch (Exception ex)
            {
                 Response.Write("

 Data:" + ex.Data + "
Message: " +
                    ex.Message + "
InnerException:" + ex.InnerException +
                               "
 Stacktrace:" + ex.StackTrace + "

");
            }

        }
        protected void btnAlterar_Click(object sender, EventArgs e)
        {
            //Objeto de conexão com o banco
            var mongo = new Mongo();

            /*Esse é o principal objeto da aplicação,
             * seria o "objeto de negócio",
             * do tipo par-valor(dicionário)
             */
            var produto = new Document();

            mongo.Connect();

            /*Variável do tipo Database,
             * executa funções de conexão
             */
            var db = mongo.getDB("BancoDeDados");

            /*Pegando a coleção, que seria o equivalente
             *a uma tabela em SQL
             */
            var produtosColecao = db.GetCollection("Produtos");

            //Definindo os valores das propriedades.
            produto["valor"] = txtValor.Text;
            produto["nome"] = txtNome.Text;
            produto["validade"] = txtDataValidade.Text;
            produto["quantidade"] = txtQtdd.Text;

            try
            {
                produtosColecao.Update(produto);
            }
            catch (Exception ex)
            {

                Response.Write("

 Data:" + ex.Data + "
Message: " +
                    ex.Message + "
InnerException:" + ex.InnerException +
                               "
 Stacktrace:" + ex.StackTrace + "

");
            }
        }

        protected void btnProcurar_Click(object sender, EventArgs e)
        {
            //Objeto de conexão com o banco
            var mongo = new Mongo();

            /*Esse é o principal objeto da aplicação,
             * seria o "objeto de negócio",
             * do tipo par-valor(dicionário)
             */
            var produto = new Document();

            mongo.Connect();

            /*Variável do tipo Database,
             * executa funções de conexão
             */
            var db = mongo.getDB("BancoDeDados");

            /*Pegando a coleção, que seria o equivalente
             *a uma tabela em SQL
             */
            var produtosColecao = db.GetCollection("Produtos");

            if (!txtValor.Text.Equals(""))
            produto["valor"] = txtValor.Text;
            if (!txtNome.Text.Equals(""))
            produto["nome"] = txtNome.Text ;
            if (!txtDataValidade.Text.Equals(""))
            produto["validade"] = txtDataValidade.Text;
            if (!txtQtdd.Text.Equals(""))
            produto["quantidade"] = txtQtdd.Text;
            try
            {
                Cursor cr = (Cursor)produtosColecao.Find(produto);
                List< Produto > lista = new List < Produto > ();

                foreach (var item in cr.Documents)
                {
                    Produto p = new Produto();
                    p.Nome = item["nome"].ToString();
                    p.Quantidade = Convert.ToInt32(item["quantidade"]);
                    p.Validade = Convert.ToDateTime(item["validade"]);
                    p.Valor = Convert.ToDouble(item["valor"]);
                    lista.Add(p);

                }

                grdBusca.DataSource = lista;
                grdBusca.DataBind();
                grdBusca.Visible = true;
            }
            catch (Exception ex)
            {
               Response.Write("

 Data:" + ex.Data + "
Message: " +
                    ex.Message + "
InnerException:" + ex.InnerException +
                               "
 Stacktrace:" + ex.StackTrace + "

");
            }
        }
    }
}

Note que coloquei uma checagem simples para que apenas campos com valores definidos( diferentes “” ou null) sejam atribuídos  às propriedades do objeto que será pesquisado no banco. Isso ocorre por que cada propriedade do objeto é utilizada como se fosse um AND em linguagem SQL, ou seja: À partir do momento que eu incluo essas propriedades no objeto da busca com valor de “” ou null, eles serão parâmetro obrigatórios na busca.

E por fim, nossa classe produto, da qual criamos uma lista para popular o GridView no método de busca da página:

   public class Produto
    {
        public Double Valor { get; set; }
        public string Nome { get; set; }
        public int Quantidade { get; set; }
        public DateTime Validade { get; set; }
    }

Bem, é isso. Os comentários estão abertos para as dúvidas, sugestões e críticas. Espero que o artigo tenha sido útil. Abraços e keep coding!

Leave a Reply