Integrando MongoDB com .Net e LINQ

Olá!

Na última sexta-feira (13 de Julho de 2012), estive presente no MongoDB São Paulo 2012. Um evento organizado pela 10Gen sobre o uso do MongoDB. Para quem não sabe o MongoDB é um banco de dados No-SQL, isto é, não trabalha com o paradigma relacional, não trabalha com colunas e nem linhas. A persistência dos dados é toda baseada na estrutura das entidades de suas classes. Isto é bastante favorável, pois não exige a existência de uma estrutura rígida baseada em um schema. Algum tempo atrás eu fiz uma série de experimentos com o Db4Objects (https://ferhenriquef.com/?s=db4o), um banco de dados orientado a objetos que funciona de forma parecida.

Um adendo: quando fiz a faculdade de Sistemas de Informação, na Universidade Presbiteriana Mackenzie, eu tive a possibilidade de escolher uma ênfase para o meu curso, e no caso escolhi a ênfase em Banco de Dados. Então, isso explica alguns dos meus posts e alguns dos experimentos neste blog. Sou vidrado em tecnologias diferentes de armazenamento de dados, mas acho que isso todos já perceberam.

mongoNet

Como não utilizamos o paradigma relacional alguns conceitos mudam de nome, veja a tabela abaixo:

Banco de Dados Relacional

MongoDB

Table

Collection

Row

Document

Column

Field

Join

Embedding

Schema

Um ponto interessante de ser notado nos bancos de dados No-SQL é que não temos o conceito de JOIN. Porque se espera, neste paradigma, que utilizemos o conceito de EMBEDDING, que significa que as entidades estão contidas umas nas outras, desta forma não fazemos usos de técnicas de normalização. Algo que foi muito bem citado por alguns dos palestrantes do MongoDB São Paulo 2012 é que: quando trabalhamos com o MongoDB, não devemos pensar como nos bancos de dados relacionais. Os conceitos de estruturação das entidades e armazenamento dos dados são muito diferentes. Mas isto é algo que temos de aprender não apenas quando trabalhamos com o MongoDB, mas com outros paradigmas de banco de dados também.

Observação: sempre que o termo “documento” for citado, tenha em mente que estamos nos referindo a um novo registro ou linha do banco de dados. Já que não estamos trabalhando com banco de dados relacionais, logo de antemão, já é interessante nos adaptarmos a sua nomenclatura correta.

Neste post vamos mostrar como integrar o MongoDB com o Microsoft .Net Framework, e vamos demonstrar como faremos uso de consultas LINQ com o MongoDB.

No meu último post (https://ferhenriquef.com/2012/07/11/mongodb-instalao/) demonstrei como instalar o MongoDB.

Para começar é preciso fazer download dos drivers do MongoDB para .Net, esse driver pode ser adquirido através deste LINQ: https://github.com/mongodb/mongo-csharp-driver/downloads. A versão que utilizei para este post é a versão 1.5.

Adicionando referências

Para fazer uso do driver para .Net faça referência as DLLs MongoDB.Driver.dll e MongoDB.Bson.dll.

Adicione os seguintes namespaces aos seus arquivos de código:

using MongoDB.Bson;
using MongoDB.Driver;
using MongoDB.Driver.Builders;
using MongoDB.Driver.Linq;

Conectando no MongoDB

Para conectarmos no banco de dados MongoDB devemos utilizar a classe MongoServer, que por meio do método Create já nos retorna uma conexão aberta e ativa.

private string connectionString = "mongodb://localhost/?safe=true";

public void ConnectingToMongoDB()
{
    // Cria conexão com o banco de dados MongoDB e já a retorna aberta
    MongoServer server = MongoServer.Create(connectionString);
}

Dica: não é necessário executar o método Disconnect para fechar a conexão com o MongoDB, devemos deixar o driver responsável por gerenciar o pool de conexões com o banco de dados. O método Disconnect fecha todas as conexões ativas com o banco de dados e atrapalha o gerenciamento das conexões pelo driver. Provavelmente, o método Disconnect deve ser chamado apenas quando tivermos certeza de que a aplicação será encerrada e mais nenhuma conexão será necessária.

Capturando uma referência para o banco de dados

Para executarmos qualquer comando é preciso capturar uma referência com o banco de dados. Para isso, utilizamos o método GetDataBase. Caso, seja invocada um banco de dados que ainda não existe no servidor MongoDB, o MongoDB irá criar esse banco de dados de forma transparente, sem que seja preciso alguma intervenção no servidor MongoDB. Para criarmos tal referência com o banco de dados, devemos fazer assim:

public void GetReferenceToDataBase()
{
    MongoServer server = MongoServer.Create(connectionString);

    MongoDatabase database = server.GetDatabase("MongoDBNet"); 
}

Utilizando Collections

Para executarmos alguma operação de CRUD precisamos instanciar uma collection. As collections no MongoDB são equivalentes as tabelas de um banco de dados SQL Server. As collections são as divisões lógicas responsáveis por agrupar um determinado tipo de dados. Para os exemplos deste post faremos uso de uma classe Contact, que contém as propriedades Name, Age, Id e PhoneNumber.

public class Contact
{
    public string Name { get; set; }
    public string PhoneNumber { get; set; }
    public int Age { get; set; }
    public ObjectId Id { get; set; }
}

Se notarmos a propriedade Id é do tipo de dados ObjectId. Este tipo de dados representa o identificador do documento dentro de sua collection, seu preenchimento é feito automaticamente pelo MongoDB. Mais detalhes veja este link: http://www.mongodb.org/display/DOCS/Object+IDs.

Para capturamos umas collection devemos passar o seu nome para o método GetCollection.

public void GetCollection()
{
    MongoServer server = MongoServer.Create(connectionString);

    MongoDatabase database = server.GetDatabase("MongoDBNet");

    var contactsCollection = database.GetCollection<Contact>("Contacts");
}

Inserindo documentos no banco de dados MongoDB

Para incluirmos novos documentos basta instanciarmos a collection que irá conter nosso documento e então passar os dados que queremos inserir para o método Insert. Desta forma os dados serão persistidos no MongoDB, independente da estrutura que nossa classe possuir.

public void InsertContact(Contact contact)
{
    MongoServer server = MongoServer.Create(connectionString);

    MongoDatabase database = server.GetDatabase("MongoDBNet");

    var contactsCollection = database.GetCollection<Contact>("Contacts");

    contactsCollection.Insert(contact);
}

Atualizando documentos no banco de dados MongoDB

O processo de atualização de documentos é tão simples quanto o processo de inclusão, basta utilizar o método Save, que irá avaliar o valor da propriedade Id, identificar qual seu respectivo documento dentro do banco de dados e então executar a atualização das propriedades.

public void UpdateContact(Contact contact)
{
    MongoServer server = MongoServer.Create(connectionString);

    MongoDatabase database = server.GetDatabase("MongoDBNet");

    var contactsCollection = database.GetCollection<Contact>("Contacts");

    contactsCollection.Save(contact);
}

Excluindo documentos no banco de dados MongoDB

Para excluir documentos do MongoDB é preciso criar uma IMongoQuery, que funcionará como critério de exclusão do documento. Esta IMongoQuery nada mais é do que um objeto que irá conter os critérios de seleção para exclusão, assim como as condições que utilizamos em um comando DELETE de um banco SQL. O exemplo abaixo demonstra o seu uso.

public void DeleteContact(Contact contact)
{
    MongoServer server = MongoServer.Create(connectionString);

    MongoDatabase database = server.GetDatabase("MongoDBNet");

    var contactsCollection = database.GetCollection<Contact>("Contacts");

    var query = Query.EQ("_id", contact.Id);
    contactsCollection.Remove(query);
}

Executando consultas com LINQ e MongoDB

A execução de consultas com sintaxe LINQ é bastante funcional e não exige nenhum configuração da base de dados MongoDB. Para executarmos consultas com LINQ devemos fazer referência ao namespace MongoDB.Driver.Linq. A dica principal é capturar a collection na qual a consulta será realizada e então começar a consulta LINQ chamando o método AsQueryable. O código abaixo apresenta duas queries construídas com LINQ sendo executadas sobre o banco de dados MongoDB.

public IEnumerable<Contact> GetAllContacts()
{
    MongoServer server = MongoServer.Create(connectionString);

    MongoDatabase database = server.GetDatabase("MongoDBNet");

    var contactsCollection = database.GetCollection<Contact>("Contacts");

    var query = from e in contactsCollection.AsQueryable<Contact>()
                select e;

    return query;
}

public IEnumerable<Contact> GetContactsByName(string name)
{
    MongoServer server = MongoServer.Create(connectionString);

    MongoDatabase database = server.GetDatabase("MongoDBNet");

    var contactsCollection = database.GetCollection<Contact>("Contacts");

    var query = from e in contactsCollection.AsQueryable<Contact>()
                where e.Name == name
                select e;

    return query;
}

Conclusões

O MongoDB é uma excelente opção de banco de dados. Apresenta ser bastante eficiente e ideal para cenários onde se precisa de muita velocidade na resposta das consultas. Os bancos de dados No-SQL se apresentam como excelente opção para diversos cenários que enfrentamos no dia-a-dia. Antes, por volta de 10 anos atrás, pouco se falava sobre este tipo de paradigma, devido à baixa qualidade das ferramentas que existiam na época, mas agora temos uma “virada de mesa”, na qual boas opções têm surgido. Acredito que em mais alguns anos teremos um uso ainda maior de banco de dados No-SQL. A dica do post é estudar o que temos no mercado, identificar o cenário no qual devemos utilizar esse tipo de tecnologia, testar algumas destas ferramentas. Estamos assistindo o início de uma revolução, podemos esperar por isso.

Ponto positivo: a documentação do MongoDB é fantástica e seu uso simples é realmente motivador.

Referências

http://www.mongodb.org/display/DOCS/CSharp+Driver+LINQ+Tutorial

http://wekeroad.com/2010/03/04/using-mongo-with-linq/

http://www.mongodb.org/display/DOCS/CSharp+Driver+Quickstart

https://www.10gen.com/presentations/mongosf-2011/c-sharp-development-with-mongodb

http://www.mongodb.org/display/DOCS/Object+IDs

Por

Fernando Henrique Inocêncio Borba Ferreira

Microsoft Most Valuable Professional – Data Platform Development

Publicidade

9 comentários sobre “Integrando MongoDB com .Net e LINQ

  1. Cara, muito legal!
    BD’s NoSql ainda é um assunto bastante polêmico, principalmente sobre os mitos que os envolvem.

    Artigos assim ajudam a desmistificar este tema! Parabéns!

  2. Olá Fernando blz?
    Bom tenho uma dúvida, que foi gerada a partir de um erro meu, rsrs…

    Como fica minha connectionString se no meu caso não for um server mongodb local e sim externo, por exemplo um https://mongolab.com da vida.
    Andei lendo a documentação do mongodb, que é ótima… Lá encontrei algo como “credentials”, tentei, e mesmo assim não consigo conectar ao banco nosql.

    Ajude-me por favor !
    Desde já agradeço.

Deixe um comentário

Preencha os seus dados abaixo ou clique em um ícone para log in:

Logo do WordPress.com

Você está comentando utilizando sua conta WordPress.com. Sair /  Alterar )

Foto do Facebook

Você está comentando utilizando sua conta Facebook. Sair /  Alterar )

Conectando a %s

Este site utiliza o Akismet para reduzir spam. Saiba como seus dados em comentários são processados.