Lançado: Linq2Couchbase v1.1.0, o provedor oficial de Linq para o Couchbase N1QL!
No início desta semana, lançamos a v1.1.0 (especificamente a v1.1.0.2) do Linq2Couchbase, o provedor oficial de Linq para o Couchbase Server e N1QL! Esta versão inclui recursos novos e experimentais, bem como correções de bugs e muitos, muitos aprimoramentos em relação à versão 1.0.X. Nesta postagem, discutiremos e demonstraremos os novos recursos quando aplicável!
Contribuintes
O Linq2Couchbase é um projeto orientado pela comunidade, o número um contribuinte (obrigado Brant!) é um membro da comunidade! Se você quiser contribuir ou enviar comentários, sinta-se à vontade para fazê-lo na seção projeto no github ou o Projeto Jira.
Principais recursos e/ou confirmações
Mais de 30 commits foram incluídos nessa versão, incluindo os seguintes recursos:
- Compatibilidade com serializadores personalizados estendendo o IExtendedTypeSerializer
- Suporte a funções de data, como DATE_DIFF, DATE_ADD, DATE_PART e DATE_TRUNC
- Suporte para operações Contains em matrizes
- Suporte para enumeração e constantes GUID em consultas
- Suporte para instruções UNION
- Documentação XML em linha aprimorada
- Suporte para consultas LINQ assíncronas usando .ExecuteAsync
- Suporte para especificar o nível de consistência da consulta para RYOW
- Tratamento de erros aprimorado
- Diversas correções de bugs
Nos próximos parágrafos, discutirei alguns dos recursos mais importantes/úteis.
Controle de alterações e proxy
Um novo recurso "experimental" que adicionamos à versão 1.1.0 é o suporte ao rastreamento de alterações por meio de objetos proxy. O caso de uso desse recurso é supor que você gostaria de modificar ou adicionar vários documentos, mas deseja que a mutação ocorra em lote em um momento posterior. Por exemplo, você deseja que o objeto BucketContext tenha a vida útil de uma solicitação da Web no ASP.NET: quando a solicitação começa, você deseja que o contexto seja criado, dentro de qualquer método de ação que você queira modificar ou adicionar documentos e, finalmente, quando a solicitação terminar, você deseja enviar tudo de volta ao servidor... ou reverter se ocorrer um erro.
O controle de alterações é ativado chamando o BucketContext.EnableChangeTracking() método antes de iniciando uma consulta.
|
1 2 3 4 5 6 7 |
var db = novo BucketContext(Ajudante de cluster.GetBucket("amostra de cerveja")); db.BeginChangeTracking(); var consulta = de x em db.Consulta() onde x.Tipo == "cerveja" selecionar x; |
Uma vez que ele é chamado de BucketContext interceptará cada linha do conjunto de resultados e criará um proxy dinâmico que fará com que todas as alterações nas propriedades ou nas propriedades dos documentos filhos voltem para o BucketContext.
Por exemplo, suponha que desejemos recuperar o primeiro documento da lista e modificar a propriedade Abv:
|
1 2 3 |
var cerveja = consulta.Primeiro(); cerveja.Abv = novo decimal(12.6); |
Quando a propriedade Abv for definido, ele acionará um evento que irá borbulhar até o BucketContext que armazenará uma referência ao documento modificado. A atualização real não ocorrerá no Couchbase até mais tarde, quando SubmitChanges é chamado.
E quanto a adicionar um novo documento? Nesse caso, você criaria o documento normalmente e, em seguida, chamaria Salvar no BucketContext:
|
1 2 3 4 5 6 7 8 9 |
var novaCerveja = novo Cerveja { Abv = 5, Categoria = "ale", Nome = "Some Brew" }; db.Salvar(novaCerveja); |
A chamada para db.Save é necessário para que o novo documento (que não é uma procuração) possa ser embrulhado em um proxy e rastreado. Finalmente, quando queremos enviar as alterações de volta ao servidor, chamamos SubmitChanges:
|
1 2 |
db.SubmitChanges(); |
Aguarde um exemplo muito mais detalhado em uma publicação futura, na qual criaremos um aplicativo ASP.NET MVC e mostraremos como o BucketContext pode ser usado em um controlador ASP.NEW como uma unidade de trabalho (UoW) com escopo para a solicitação da Web.
Serializadores personalizados por meio do IExtendedTypeSerializer
Há algum tempo, o SDK do Couchbase .NET oferece suporte a serializadores personalizados. O serializador padrão é baseado no NewtonSoft JSON.NET, que é um serializador completo e bem suportado; no entanto, em alguns casos, você pode querer usar outro serializador, como o Jil ou Pilha de serviços's Text. Para oferecer suporte a outros serializadores JSON que não sejam da NewtonSoft em Linq2CouchbaseAdicionamos uma nova interface chamada IExtendedTypeSerializer. Além disso, o mecanismo de serialização foi estendido para incluir o QueryRequest como um ponto de integração, o que significa que um serializador personalizado pode ser usado por solicitação, em vez de uniformemente em todo o Couchbase .NET SDK.
Suporte para funções de data N1QL
O N1QL oferece suporte a muitas funções Date que não se traduzem diretamente em métodos DateTime do .NET. Nesta versão, adicionamos suporte a várias dessas funções Função de data N1QLs incluindo:
- DATE_DIFF_STR
- DATE_ADD_STR
- DATE_PART_STR
- DATE_TRUNC_STR
Além disso, foi adicionada uma nova enumeração chamada N1QLDatePart para o parâmetro de parte da data aceito por cada função. Você pode ler mais sobre como trabalhar com datas aqui.
Atualize para o Relinq 2.0 e use o ILRepack
Relinqa biblioteca de código aberto que o Linq2Couchbase (NHibernate e Estrutura de entidades 7 também) lançou recentemente a versão 2.0, portanto, atualizamos para a mais recente. Para facilitar o uso do Linq2Couchbase com o EF 7 no mesmo projeto e reduzir o número de dependências necessárias, o Relinq (e o Castelo.Core) foram mescladas no momento da compilação usando ILRepack no pacote NuGet.
Suporte para UNIÃO e UNION ALL Declarações
Para combinar os resultados de mais duas consultas em um único conjunto de resultados, o N1QL tem dois comandos especiais: UNIÃO e UNION ALL.
UNION retorna os resultados distintos de cada consulta e agora é compatível com o Linq2Couchbase. Por exemplo, a seguinte consulta Linq:
|
1 2 3 4 5 6 7 8 |
var consulta = db.Consulta(mockBucket.Objeto) .Onde(e => e.Tipo == "cerveja") .Selecione(e => novo { e.Nome }) .União( db.QueryBrewery>(mockBucket.Objeto) .Onde(e => e.Tipo == "cervejaria") .Selecione(e => novo { e.Nome })); |
Será gerada em uma consulta N1QL semelhante a esta:
|
1 2 3 4 |
SELECIONAR `Extensão1`.`nome` como `Nome` DE `padrão` como `Extensão1` ONDE (`Extensão1`.`tipo` = "cerveja) UNIÃO SELECIONAR `Extensão2`.`nome` como `Nome` DE `padrão` como `Extensão2` ONDE (`Extensão2`.`tipo` = "cervejaria); |
UNION ALL retorna duplicatas e a sintaxe do Linq é um pouco diferente, pois usamos o método Concat:
|
1 2 3 4 5 6 7 8 |
var consulta = db.Consulta(mockBucket.Objeto) .Onde(e => e.Tipo == "cerveja") .Selecione(e => novo { e.Nome }) .Concat( db.Consulta(mockBucket.Objeto) .Onde(e => e.Tipo == "cervejaria") .Selecione(e => novo { e.Nome })); |
A consulta N1QL emitida terá a seguinte aparência:
|
1 2 3 4 |
SELECIONAR `Extensão1`.`nome` como `Nome` DE `padrão` como `Extensão1` ONDE (`Extensão1`.`tipo` = "cerveja UNIÃO TODOS SELECIONAR `Extensão2`.`nome` como `Nome` DE `padrão` como `Extensão2` ONDE (`Extensão2`.`tipo` = "cervejaria |
Observe que vários UNIÃOs também podem ser aplicados!
Consultas assíncronas de Linq
Outro recurso interessante que foi adicionado é o suporte a consultas Linq assíncronas usando o assíncrono e aguardar que são incorporados ao C#/.NET. Observe que há suporte para IEnumerable e escalar (Sum, First(), Any()).
Aqui está um exemplo que retorna um valor IEnumerable:
|
1 2 3 4 5 |
var cervejas = de b em contexto.Consulta() selecionar b; var resultados = (aguardar cervejas.Pegue(1).ExecuteAsync()).ToList(); |
Aqui está outro exemplo que demonstra a execução de um valor escalar:
|
1 2 3 4 5 |
var cervejas = de b em contexto.Consulta() selecionar b; var resultado = aguardar cervejas.ExecuteAsync(p => p.Média(q => q.Abv)); |
Em ambos os casos, a solicitação de consulta será executada de forma não bloqueada (como um pool de threads). Coisas legais.
Como obtê-lo
Você pode obter a versão 1.1.0 do Linq2Couchbase: