Uma das vantagens significativas de trabalhar com o Couchbase Server 2.0 é seu esquema flexível. Os documentos são armazenados como JSON, permitindo registros implicitamente estruturados que não impõem ordem uns aos outros. No mundo real, essa "estrutura implícita" vem do seu aplicativo. Quando você cria um novo usuário no seu aplicativo, o documento associado é uma versão serializada em JSON do seu objeto de domínio.
{
[JsonIgnore]
público string Id { obter; definir; }
[JsonProperty("nome de usuário")]
público string Nome de usuário { obter; definir; }
[JsonProperty("senha")]
público string Senha { obter; definir; }
[JsonProperty("tipo")]
público Tipo de string { obter { retorno "usuário"; } }
}
//armazenado como { "username" : "hmoody", "password" : "b3cca" }
Embora essa abordagem seja comum em aplicativos em que os documentos são lidos e gravados a partir de objetos de domínio bem definidos, há casos em que a estrutura dos documentos é intencionalmente menos bem definida. Nesses casos, talvez não seja viável ter um objeto de domínio por tipo de documento.
Embora em linguagens como Python ou Ruby possa ser comum usar uma abordagem menos orientada a objetos (por exemplo, dicionários ou hashes), em linguagens fortemente tipadas, como C# ou Java, é muito mais comum representar os dados do aplicativo usando objetos de dados fortemente tipados, geralmente chamados de objetos simples (Java|C#). Entretanto, certamente é possível usar abordagens de linguagem dinâmica com essas linguagens.
Quando um usuário perguntou recentemente no StackOverflow Como extrair documentos JSON do Couchbase e transformá-los em objetos C# de tipagem livre, propus duas opções. No restante deste post, descreverei alguns métodos básicos de extensão que você pode usar para adotar uma abordagem semelhante com seus dados.
A primeira abordagem é armazenar Dicionário
Para salvar e ler esse documento, adicionaremos métodos de extensão para salvar e recuperar dicionários. Esses métodos ficarão dentro de uma nova classe estática chamada CouchbaseDynamicExtensions.
O primeiro método simplesmente envolverá o método padrão ExecuteStore mas encapsulará algumas coisas. Primeiro, ele cuidará da serialização do Dictionary para JSON usando a biblioteca Newtonsoft.JSON. Você pode modificar as configurações do serializador para dar suporte a camel casing ou outras opções de formatação de JSON. Deixei os padrões no lugar. Em segundo lugar, encapsulei o IStoreOperationResponse em um retorno de tupla indiscutivelmente mais simples. Como as tuplas são comumente retornadas em linguagens dinâmicas, e eu estou tentando ser mais dinâmico, essa pareceu ser uma abordagem apropriada.
string chave, Dicionário<string, objeto> dicionário)
{
var json = JsonConvert.SerializeObject(dicionário);
var result = cliente.ExecuteStore(storeMode, key, json);
se (!resultado.Sucesso)
{
se (resultado.Exceção != nulo) lançar resultado.Exceção;
retorno Tuple.Criar(falso, resultado.StatusCode.HasValue ? resultado.StatusCode.Valor : –1, resultado.Mensagem);
}
retorno Tuple.Criar(verdadeiro, 0, string.Vazio);
}
Obter o Dictionary de volta do JSON armazenado simplesmente inverte o processo. Novamente, estou envolvendo o IGetOperationResult em um Tuple e cuidando da desserialização do JSON armazenado em um Dicionário
{
var result = cliente.ExecuteGet<string>(chave);
se (!resultado.Sucesso)
{
se (resultado.Exceção != nulo) lançar resultado.Exceção;
retorno Tuple.Criar<bool, int, string, Dicionário<string, objeto>>
(falso, resultado.StatusCode.HasValue ? resultado.StatusCode.Valor : –1, resultado.Mensagem, nulo);
}
var dict = JsonConvert.DeserializeObject<Dicionário<string, objeto>>(resultado.Valor);
retorno Tuple.Criar(verdadeiro, 0, string.Vazio, dict);
}
O salvamento e a recuperação são simples (não se esqueça de adicionar um using ao namespace da classe de extensão).
se (resultado.Item1)
{
var dict = cliente.GetDictionary("user_1").Item4;
Console.WriteLine(ditado); //deve ser o resultado de Dictionary.ToString()
}
Uma abordagem mais interessante seria aproveitar as vantagens do novo dinâmico digitação e o ExpandoObject classe. Esses recursos permitem que os desenvolvedores instruam o compilador a realizar a verificação de tipo em tempo de execução, e não em tempo de compilação. Trabalhar com documentos JSON é um ótimo caso de uso para a dinâmica.
Os métodos de extensão dinâmica são quase idênticos, exceto pelo fato de que antes havia dicionários e agora há tipos dinâmicos.
string key, ExpandoObject obj)
{
var json = JsonConvert.SerializeObject(obj);
var result = cliente.ExecuteStore(storeMode, key, json);
se (!resultado.Sucesso)
{
se (resultado.Exceção != nulo) lançar resultado.Exceção como Exceção;
retorno Tuple.Criar(falso, resultado.StatusCode.HasValue ? resultado.StatusCode.Valor : –1, resultado.Mensagem);
}
retorno Tuple.Criar(verdadeiro, 0, string.Vazio);
}
público estático Tuple<bool, int, string, ExpandoObject> GetDynamic(este Cliente ICouchbaseClient, string chave)
{
var result = cliente.ExecuteGet<string>(chave);
se (!resultado.Sucesso)
{
se (resultado.Exceção != nulo) lançar resultado.Exceção;
retorno Tuple.Criar<bool, int, string, ExpandoObject>
(falso, resultado.StatusCode.HasValue ? resultado.StatusCode.Valor : –1, resultado.Mensagem, nulo);
}
var obj = JsonConvert.DeserializeObject<ExpandoObject>(resultado.Valor);
retorno Tuple.Criar(verdadeiro, 0, string.Vazio, obj);
}
Usando instâncias dinâmicas em seu código, você pode salvar e recuperar dados de e para o Couchbase Server. Observe que você também pode ler qualquer documento JSON em um ExpandoObject usando a abordagem de código abaixo. Para testar isso, você pode chamar GetDynamic com uma chave de "user_1".
usuário2.Nome de usuário = "jzablocki";
usuário2.Preferências = novo ExpandoObject();
usuário2.Preferências.Tema = "verde";
usuário2.Preferências.Fuso horário = "EST";
cliente.StoreDynamic(StoreMode.Conjunto, "user_2", user2 como ExpandoObject);
var getResult = cliente.GetDynamic("user_2");
se (getResult.Item1)
{
item dinâmico = getResult.Item4;
Console.WriteLine(item.Preferências.Tema);
}
Há abordagens alternativas para as extensões dinâmicas que exigem a conversão, devido às limitações de chamar um método de extensão com argumentos dinâmicos. Para simplificar as coisas, eu me limitei a ExpandoObject argumentos.
Muito bom o post, obrigado por compartilhar...............
John, sua postagem é muito útil.