Hoje, a Couchbase tem o prazer de anunciar o lançamento da versão GA do provedor oficial de LINQ para o Couchbase Server e a linguagem de consulta quente para documentos JSON, N1QL! O objetivo do provedor é fornecer um ORM/ODM simples e fácil de usar que seja mais próximo do Linq2SQL do que o EntityFramework ou o NHibernate, que são detalhados e podem ser complexos.

Embora o objetivo seja a simplicidade, não subestime o poder do Linq2Couchbase; ele é uma implementação totalmente funcional do Linq com suporte estendido para todos os recursos incríveis do N1QL!

Nesta postagem, abordaremos os conceitos básicos para começar a usar o Linq2Couchbase, os principais atores da API e a integração com o ASP.NET e o Owin/Katana. Em postagens posteriores, entraremos em mais detalhes sobre as especificidades e os detalhes do Linq2Couchbase!

A arquitetura

O provedor é, na verdade, apenas outra camada sobre o SDK; o provedor lida com a análise e a geração de consultas e o SDK lida com a solicitação e o mapeamento dos resultados. O provedor usa Re-linq internamente para criar uma árvore de sintaxe abstrata (AST) a partir da consulta Linq, que é então usada para emitir a instrução N1QL. Observe que o Re-linq é usado tanto pelo NHibernate quanto pelo EntityFramework, portanto, você está em boas mãos!

Primeiros passos

A fonte está disponível em Github e o pacote está disponível em NuGetSe você usar o gerenciador de pacotes NuGet para instalar o Linq2Couchbase, todas as dependências, inclusive o Couchbase.NET SDK, serão tratadas para você.

Para instalar o Linq2Couchbase usando o gerenciador de pacotes NuGet (supondo que você já tenha criado um projeto do Visual Studio), abra o gerenciador de pacotes clicando com o botão direito do mouse em "Manage Nuget Packages" e procurando por Linq2Couchbase ou usando a linha de comando do gerenciador de pacotes:

Depois de fazer isso, o projeto terá todas as dependências necessárias. Em seguida, você precisará instalar o Couchbase Server localmente ou por meio de uma VM. O link para download do Couchbase Server é aqui. Para as VMs, use vagabundos que usa o Puppet e o Vagrant para instalar um cluster de servidores Couchbase. Certifique-se de instalar o Couchbase 4.0! Se estiver usando Vagrants, provisione o cluster:

Quando você tiver um servidor ou cluster do Couchbase, configure o servidor ou cluster e certifique-se de que pelo menos um nó seja um nó de índice e um nó seja um nó de consulta. Isso será feito na primeira etapa da "Configuração do servidor" ou quando você adicionar um servidor adicional ao cluster. Além disso, adicione o conjunto de dados "beer-sample" ao cluster durante a configuração ou na guia Settings>Samples (Configurações>Amostras) depois de configurar o cluster ou a instância.

Agora que sua instância ou cluster do Couchbase está configurado, você precisará criar um índice primário no bucket "beer-sample". Para fazer isso, navegue até C:Arquivos de programasCouchbaseServerbin ou, se estiver usando vagrants (ou linux) /opts/couchbase/binusando um prompt de comando. Em seguida, digite cbq ou ./cbq (no Linux) para iniciar a consulta CIL e depois:

Isso criará um índice primário no bucket beer-sample. Observe os sinais de retrocesso "`", pois eles são necessários para escapar do "-" em beer-sample. Agora você está pronto para escrever algum código!

Criando o BucketContext

O principal objeto para trabalhar com o bucket é o BucketContext. O BucketContext é análogo ao DataContext no Linq2Sql e ao DbContext no EntityFramework. Sua finalidade principal é fornecer uma interface para criar consultas e enviá-las ao servidor Couchbase.

Você pode usar o BucketContext como um objeto autônomo ou pode derivar dele e criar um objeto de tipagem forte que mapeie as propriedades para os tipos em seu modelo de domínio e de balde. Neste exemplo, farei a segunda opção:

public class BeerSample : BucketContext { public BeerSample() : this(ClusterHelper.GetBucket("beer-sample")) { } public BeerSample(IBucket bucket) : base(bucket) { DocumentFilterManager.SetFilter(new BreweryFilter()); } public IQueryable Beers { get { return Query(); } } public IQueryable Breweries { get { return Query(); } } }

O bucket de amostras de cerveja (um bucket é semelhante a um banco de dados em um sistema RDBMS) contém documentos que são "tipificados" como "cervejaria" e "cerveja". Esse sistema informal de tipos permitirá consultar o bucket e retornar documentos de cervejaria ou documentos de cerveja por meio de um predicado (WHERE type="beer", por exemplo). No código acima, definimos propriedades explícitas que retornam IQueryable

Um exemplo de consulta

Você verá que o uso do Linq2Couchbase é praticamente idêntico ao do Linq2SQL ou do EF:

Uma vez que você tenha uma referência ao BucketContext, basta consultá-lo como faria com qualquer outro provedor Linq. Todas as palavras-chave Linq são suportadas, bem como construções N1QL como ON KEYS, NEST e UNNEST! Em uma postagem posterior, abordaremos tudo isso com muito mais detalhes!

O modelo de documento

No contexto BeerSample acima, os objetos Beer e Brewery serão os alvos de nossas projeções Linq e correspondem ou mapeiam documentos JSON equivalentes em nosso bucket (beer-sample). Aqui está uma listagem de cada um (observe que esta é uma listagem parcial, as classes em sua totalidade podem ser encontradas aqui):

É claro que isso mapeia os documentos "cerveja"; observe o atributo DocumentTypeFilter. Isso adicionará "automaticamente" um predicado ou cláusula WHERE que filtra pelo tipo "cerveja" a todas as consultas que têm como alvo esse documento. O atributo DocumentTypeFilter é uma das duas maneiras de aplicar um filtro, a menos que você adicione manualmente o predicado a cada consulta.

Esse é o objeto para o qual os documentos da "cervejaria" serão mapeados. Observe que não há nenhum atributo DocumentTypeFilter definido explicitamente; isso ocorre porque o construtor do contexto BeerSample adicionará o filtro ao DocumentFilterManager. Essa é apenas uma abordagem diferente para o mesmo problema: adicionar um predicado a uma consulta para filtrar por tipo.

Integração com ASP.NET ou Owin/Katana

Há um padrão muito distinto para usar o SDK do Couchbase .NET em projetos ASP.NET ou Katana/OWin. Como o BucketContext usa o SDK do Couchbase .NET, você precisará seguir esse padrão para aproveitar o cache de objetos no SDK e as conexões TCP compartilhadas. Felizmente, é um padrão muito simples:

Usando o Global.asax no ASP.NET

Em um aplicativo ASP.NET que usa o Global.asax, você aproveitará os manipuladores de eventos Application_Start e Application_End para criar e destruir os objetos Cluster e Bucket dos quais o BucketContext depende.

Aqui estamos criando a configuração (a propósito, isso também pode vir do App.Config) e, em seguida, inicializando o objeto ClusterHelper. Finalmente, quando o aplicativo é encerrado, estamos destruindo os objetos Cluster e Bucket de longa duração no manipulador Application_End. Esse será um desligamento gracioso e as construções no nível do sistema operacional serão devolvidas ao sistema operacional em tempo hábil.

Uso do Setup.cs no Owin/Katana

Nos aplicativos hospedados na Owin/Katana, seguimos um padrão semelhante, apenas usamos um método diferente, a classe Setup.cs.

Aqui, criamos e inicializamos o ClusterHelper quando o método Configuration é executado na inicialização e, em seguida, registramos um delegado que será acionado quando o aplicativo for encerrado, fechando nosso ClusterHelper e liberando recursos.

Injetando em seus controladores

O BucketContext em si assume as características do padrão Unit of Work; você pode criar um para cada solicitação e, como o ClusterHelper gerencia as referências (supondo que você esteja seguindo as orientações acima), a instância será simplesmente GC no final da solicitação.

A maneira mais simples de fazer isso é simplesmente usar Injeção de dependência (o padrão) em seus controladores para criar a instância quando o controlador for criado, por exemplo:

Agora, basta usar o BucketContext em seus métodos de ação:

Mais uma vez, como o contexto é um objeto leve e de curta duração, você pode definir o escopo para a solicitação e injetá-lo lá, reutilizando-o para todos os controladores invocados nessa solicitação.

O que está por vir?

Muito em breve, o próximo grande recurso será o Change Tracking usando proxies. Além disso, espere por correções de bugs, aprimoramentos de desempenho e outros recursos destinados a tornar o Linq2Couchbase um ODM/ORM leve e com todos os recursos!

Se houver um recurso que você deseja, uma correção de bug ou se quiser contribuir, agradecemos todos os tipos de feedback, tanto os bons quanto os ruins.

  • O Jira é aqui.
  • O projeto Githb é aqui.

O Linq2Couchbase é um projeto de código aberto voltado para a comunidade, portanto, dê uma olhada nele e, se quiser contribuir, faça-o!

Agradecimentos especiais

Um agradecimento especial a todos os que contribuíram com o projeto (afinal, trata-se de código aberto!), especialmente a Brant Burnett de Software Centeredge que contribuíram significativamente para o projeto e a documentação do NuGet!

Autor

Postado por Jeff Morris, engenheiro de software sênior, Couchbase

Jeff Morris é engenheiro de software sênior da Couchbase. Antes de ingressar na Couchbase, Jeff passou seis anos na Source Interlink como arquiteto da Web corporativa. Jeff é responsável pelo desenvolvimento dos SDKs do Couchbase e pela integração com o N1QL (linguagem de consulta).

Deixar uma resposta