Rodrigo Sendin

.NET Framework, C#, ASP.NET, Visual Studio, WPF, Silverlight, Expression Blend, Arquitetura de Sistemas, Desenvolvimento de Software e afins.

domingo, 15 de fevereiro de 2009

db4o (parte 3) – QBE: Query-By-Example

O db4o oferece quatro formas diferentes de se realizar queries: Query By Example (QBE), Native Queries (NQ), SODA API e LINQ. Neste POST veremos como funciona o QBE.

Query-By-Example, ou simplesmente QBE é a forma mais simples e indicada para usuários que estão iniciando com o db4o. Este é um conceito de construção de queries antigo, que foi criado em paralelo com a linguagem SQL nos anos 70.

A idéia é criar um protótipo que servirá de exemplo para os registros que devem ser retornados pela pesquisa. Este tipo de query é muito comum na orientação a objetos. Se quiser conhecer mais sobre o conceito, dê uma olhada neste artigo publicado no Wikipédia: http://en.wikipedia.org/wiki/Query_by_Example

No db4o quando você usa o QBE, deve fornecer como parâmetro um objeto de template. O db4o irá retornar todos os objetos que tiverem as propriedades iguais aos do objeto template, ignorando apenas as propriedades que contiverem valores defaults.

Fazendo uma consulta na base de dados criada no POST anterior, veja o exemplo abaixo:


Neste exemplo estamos executando uma Query By Example, passando “como exemplo” um objeto da classe Country que possuí a propriedade ID = “BR”. O valor null para strings e o zero para inteiros, são considerados valores defaults, e portanto essas propriedades não entram como condição para esta pesquisa. Sendo assim, o resultado dessa query irá retornar apenas o país Brasil, veja na imagem abaixo:


Obviamente esse tipo de Query é bastante limitado, já que restringe as nossas possibilidades de pesquisa a retornar apenas objetos que tenham as propriedades iguais às do objeto template. Além disso, você não pode utilizar operadores lógicos como OR, AND ou NOT. Porém, é uma forma muito útil e fácil de pesquisar um determinado objeto, através de propriedades chaves, como um ID.

O QBE também pode ser utilizado como uma forma simples e rápida de retornar todos os objetos de uma determinada classe, veja o exemplo do código abaixo:


O resultado é a lista de todos os países armazenados no database. Veja na figura a seguir:


Como disse no início, essa é uma forma bem simples para realizar consultas no db4o, e indicada quando estamos iniciando. No próximo POST veremos como funcionam as Native Queries (NQ), para principalmente endereçar tipos de pesquisa não suportados pelo QBE.

Grande Abraço e até o próximo!

Marcadores: , , ,

domingo, 8 de fevereiro de 2009

db4o – CRUD (parte 2)

Vamos agora ver como criar o nosso primeiro banco de dados no db40, e como realizar as quatro operações básicas de qualquer banco de dados: Inclusão, Alteração, Exclusão e Consulta (CRUD = Create, Read, Update e Delete).

A primeira coisa que fazemos quando vamos criar um banco de dados é definir a sua estrutura. Porém aqui estamos falando de um banco de dados orientado a objetos, e não um database relacional como o SQL Server ou Oracle.

A primeira coisa que você tem que saber sobre os databases OO é que a estrutura de dados é definida através de Classes e não de Tabelas. Na prática, o que temos que fazer é criar nossas classes em C#, no próprio Visual Studio.

Vou começar com um exemplo muito simples, porém preparado para comportar os exemplos mais avançados que veremos nos posts futuros. Sendo assim, criei no Visual Studio uma Solution chamada Algoritma, e dentro dessa solution adicionei um projeto do tipo Class Library, chamado Algoritma.Model. Será aqui que iremos criar as classes que definirão a estrutura de dados do nosso database.

Você pode criar suas classes usando o diagrama de classes do Visual Studio. Com ele o processo de modelagem fica bem mais simples e prático. Veja na imagem abaixo que eu criei uma classe chamada Country.



Através do Diagrama do Visual Studio nós podemos criar a nossa estrutura de classes, porém não vamos fugir de por a mão no código, para fazer alguns ajustes nestas classes. Sendo assim, edite a classe Country.cs para que fique como mostra o código abaixo:



Note que criamos três propriedades simples, que irão armazenar o ID do país, que será uma simples sigla, o Nome e um inteiro que irá representar a população daquele país. Em seguida temos um construtor simples que apenas inicializa as propriedades do objeto que está sendo instanciado.

Mais abaixo temos outros dois métodos. O AddPopulation() que simplesmente adiciona valores à População. Não tem um objetivo muito prático, mas vai nos ajudar a entender que apesar de estarmos falando de armazenamento, podemos definir métodos nas nossas classes.

E por fim o método ToString(), que foi sobrecarregado da classe Objects, e aqui irá retornar uma string que exibe todas as propriedades do país.

A princípio essa será a única classe que iremos criar. Veremos agora como criar um banco de dados no db4o e armazenar instancias da classe Country nele.

Antes disso você deve ter observado que até agora não utilizamos nenhum recurso do db4o. Esse é um diferencial importante, pois podemos definir nossas classes da maneira que quisermos, e o db4o se encarregará de armazenar os objetos no database.

Para criarmos nosso banco de dados no db40, vamos adicionar um novo projeto na Solution, agora do tipo Console Application. Neste exemplo eu criei um projeto chamado Algoritma.ConsoleApp.

De cara, neste projeto devemos adicionar duas referencias. Uma referencia ao projeto Algoritma.Model, para que possamos ter acesso à nossa classe Country. E uma referencia à DLL Db4objects.Db4o.dll, que como foi dito no post anterior, é a DLL principal do db4o. Essa DLL você provavelmente irá encontrar no seguinte caminho: C:\Program Files\Db4objects\db4o-7.4\bin\net-3.5.

Com as duas referências criadas, vamos agora ao processo de criação e abertura do banco de dados, que nada mais é do que uma simples linha de código na classe Program.cs, veja a seguir:



Como você pode notar estamos criando uma instancia da interface IObjectContainer, através do método estático OpenFile() da classe Db4oFactory. Veja que este método aponta para um arquivo com extensão .yap. Esta é a extensão dos databases do db4o, que neste caso foi nomeado como Algoritma.yap. Caso o arquivo não exista, ele será criado e aberto, caso exista será apenas aberto.

Em seguida temos uma estrutura try/finally que irá garantir que o database seja devidamente fechado assim que terminarmos de utilizá-lo.

Muito bem, com isso já podemos fazer nossos primeiros testes CRUD. Comecemos com um método de inclusão. Basta incluir o método do código abaixo e fazer a sua chamada no método Main, conforme você vê na própria listagem a seguir:




O Método InsetCountries está criando 3 instancias da classe Country, e armazenando-as no database através do método Store() que temos no IObjectContainer. Note que ao final estamos chamando o método Commit(). Este método está implicitamente concluindo a transação. A partir do momento em que abrimos o database, já estamos em uma transação. E após a chamada do método Commit() a transação atual foi concluída, e outra iniciada.

Execute sua aplicação e veja que os países são inclusos e exibidos na Console. Confira na Figura abaixo.



De tão simples parece estranho não é? Parece que não aconteceu nada, que estes objetos estão apenas na memória, e que ao finalizar a aplicação eles vão ser perdidos. Mas não, eles foram gravados em disco, lá no arquivo Algoritma.yap, e portanto estão armazenados no database db4o.

Vamos à prova. Voltando ao código da classe Program.cs, inclua agora o método SelectCountries conforme mostra o código abaixo, e no método Main(), substitua a chamada do método InsertCountries(), pelo SelectCountries().



Note que estamos fazendo uma consulta que irá retornar um IList contendo dos os objetos da classe Country que existirem no database. Essa é uma das diversas formas que existem para a realização de queries no db40. Veremos no decorrer dos exemplos outras formas.

Execute a aplicação e veja como mostra a imagem abaixo, que é exibido o total de países cadastrados, juntamente com os dados detalhados de cada país.



Abaixo temos o método UpdateCountry, que como você pode ver está realizando um outro tipo de pesquisa, utilizando o padrão QBE. QBE quer dizer Query By Example, ou “Consulta por Exemplo”. Isso significa que o db4o deverá nos retornar todos os objetos armazenados que forem iguais ao do exemplo passado no parâmetro.



A condição é realizada ignorando as propriedades definidas como null, ou zero no caso do inteiro. Com isso estamos recuperando apenas um objeto, no caso o com o ID igual a “FR”.

Com o objeto recuperado do database, podemos fazer a alteração que desejarmos e salvarmos essa alteração através do mesmo método Store(). Veja o resultado da execução deste código na figura a seguir:



Para finalizar segue o código do método DeleteCountry, que também usa QBE para recuperar o país US do database, e excluí-lo do banco.



O resultado da execução deste método você confere na figura abaixo:



Este foi apenas um exemplo básico de como criar um database db4o e realizar as operações mais simples com ele.

Mas aqui nós já podemos ver que o processo de gravação e recuperação dos dados é muito simples, bem mais simples do que estamos acostumados em ambientes de mapeamento objeto / relacional. Veremos muito mais facilidades nos próximos exemplos.

Nos próximos POSTs iremos ver quais são as principais formas de realizar Queries com o db40. Grande Abraço e até lá!

Marcadores: , , ,

terça-feira, 9 de setembro de 2008

LINQPad

Recentemente, na coluna .NET Brasil que escrevo na .NET Magazine falei um pouco sobre o dilema de se escrever queries em LINQ, e como podemos nos acostumar a essa nova forma de se fazer pesquisas no banco de dados.

Se você nunca ouviu falar do LINQ, segue uma breve definição: Esta é a sigla para Language Integrated Query que é uma linguagem integrada ao C# e VB.NET para a execução de queries. A idéia é substituir o uso da linguagem SQL por uma linguagem compatível, semelhante e integrada ao código gerenciado .NET.

A partir do momento em que você vai colocando em prática o LINQ em suas aplicações, surge um dilema sério: Como nos acostumar a escrever queries em LINQ, já que estamos tão acostumados a escrever comandos em SQL?

As diferenças não são tão grandes assim, mas há uma mudança considerável na ordem em que escrevemos os comandos. O que antes escrevíamos assim:

Agora escrevemos assim (C#):



Veja que primeiro vem o FROM, em seguida o WHERE e o ORDERBY e só no final é que vem a clausula SELECT. Com essa inversão das cláusulas, ganhamos o benefício do intelisense, na hora de escolher os campos que serão retornados pela consulta.

Não é fácil para quem está começando e já é acostumado com o jeito antigo. Uma ferramenta essencial nesse momento é o LINQPad, do Joseph Albahari. É uma ferramenta gratuita que você pode baixar a partir deste link: http://www.linqpad.net/

No LINQPad podemos criar conexões com nossos databases e executar consultas utilizando a linguagem LINQ. Seria o equivalente à ferramenta de queries que temos no SQL Server Management Studio. Veja na figura abaixo um exemplo de query executada no LINQPad:


Essa é sem dúvida uma ferramenta obrigatória para quem está começando no LINQ, não deixe de baixar e utilizar!

Grande Abraço e até a próxima!

Marcadores: , ,

domingo, 31 de agosto de 2008

C# 3.0 : Extension Methods

A versão 3.0 da linguagem C# nos trouxe muitas melhorias, que se deram principalmente pela viabilização do LINQ (Language Integrated Query). Muitas destas novidades podem ser aproveitadas no nosso dia a dia, e neste Post eu vou falar um pouco sobre uma delas: os Extension Methods.

Os Extension Methods ou métodos de extensão são muito parecidos com os métodos estáticos, que podem ser chamados sem a necessidade de instanciarmos um objeto da classe.

Porém o objetivo de um extension method, é “adicionar” métodos a um uma classe já existente, sem a necessidade de modificarmos esta classe. Legal né?


Um exemplo: Que tal seria se tivéssemos um método ToZeroLeft em objetos da classe int? Ajudaria bastante quando precisamos colocar zeros à esquerda de um valor, e gravá-lo em uma string.


Este é apenas um exemplo, com certeza você vai achar diversas outras aplicações para os extensions methods. Chega de conversa e vamos logo ver como isso funciona.


Os seus Extension Methods devem ser criados como métodos estáticos, de preferência em uma classe destinada apenas para estes tipos de métodos. O primeiro parâmetro do método deve ser precedido do modificador this. E o seu tipo define o tipo que será “modificado”, ganhando este novo método. Veja o exemplo abaixo:


Toda vez que importarmos este namespace ExtensionMethods em qualquer outra classe, as variáveis do tipo int “ganharão” o método ToLeftZeros, veja o exemplo abaixo:


Note que a variável numero do tipo int possuí agora o extension method ToLeftZeros. Veja que no intelisense este método aparece com uma pequena seta apontando para baixo, indicando que este é um método de extensão.

Para nós, “usuários finais do C#”, a impressão é que modificamos a classe int, adicionando a ela um novo método. Porém por de trás dos panos, o compilador irá transformar isso em uma chamada ao método estático que criamos.

Como disse no começo, esta é uma funcionalidade que veio no C# 3.0 para viabilizar algumas features do LINQ. Para comprovar isso é simples, adicione uma referencia ao namespace System.Linq e veja o que acontece à suas Arrays:


Note que elas vão “ganhar” uma série de métodos relacionados à linguagem LINQ, como por exemplo o OrderBy.

Espero que faça um ótimo uso dos Extension Methods. Abaixo coloco algumas ótimas referencias sobre este tema:

Grande Abraço e até a próxima!

Marcadores: , ,