Fernando Amaral
Untitled Document

LBLGen Pro 2.0, a melhor ferramenta ORM para .NET
13 de outubro de 2006

As vésperas de iniciar um novo projeto e enquanto o ObjectSpaces não vem, estavam à procura de uma ferramenta ORM. No último projeto tinha utilizado um
pequeno Software que havimos desenvolvido: ele apenas gerava blocos de código a partir do schema do banco: de certa forma primitiva, porém eficiente.
Tratando-se de uma decisão importante, resolvi investir algum tempo investigando as opções disponíveis no mercado. Minha preferência era encontrar uma ferramenta
comercial, nada de Open Source. Mesmo assim resolvi experimentar tudo. No final, testei mais de trinta (isso mesmo, trinta!) ferramentas diferentes.
A primeira tentativa foi o NHibernate, que com certeza é o mais popular: uma versão do Hibernate já há algum tempo utilizado por desenvolvedores Java. Logo o
abandonei por diversos motivos: Esta em beta; diversas queixas com relação a desempenho; pouco documentado; não oferece nenhuma boa GUI para sua
utilização.


Depois investiguei o ORM.NET, produzida pelo Olero Software, uma ferramenta que já tinha testado superficialmente a algum tempo atrás. Para minha surpresa, o
produto virou Open Source e esta disponível para download no Sourceforge. Apesar de estar praticamente abandonado, gostei muito do produto, e estava tentado a
utilizá-lo. Porém percebemos que o mesmo gerava alguns relacionamentos duplicados quando a chave primária da tabela era composta. Procurando entender
porque, achei a seguinte explicação de um de seus mantedores no SourceForge:


“the tool does not support composite keys. Besides, composite keys are a bad RDBMS design.”


Porque ninguém avisou o Date sobre isso?


Quando estava quase desistindo e voltando pra nossa própria ferramenta, a surpresa: LBLGEN Pro, da Solutions Design, que há poucos dias havia lançado a versão 2.0 deste produto. A surpresa foi maior porque eu já havia testado a primeira versão do produto, a qual tinha achado bem deficiente. Vamos ver o que a ferramenta tem de tão especial.


O primeiro ponto a favor é que é um produto comercial , vi que a empresa possui um sistema de Help Desk e um fórum bem ativo. É diferente quando há alguém do
outro lado com obrigação de te auxiliar e resolver seus problemas. Apesar de a versão ser nova, tem tudo para dar certo e não acabar abandonado como o
ORM.NET.

Utilizado o LLBLGen Pro


Este exemplo eu criei com a versão Demo do LLBLGen Pro, que você pode baixar de http://www.llblgen.com. Esta versão é totalmente funcional por 30 dias. Utilizei ainda o Visual Studio 2005 e SQL Server 2005, banco de dados de demonstração AdventureWork. Você pode utilizar a versão 2000/ 2003 do Visual Studio, ou ainda diversos outros SGBD suportados pelo produto, para maiores detalhes consulte a ajuda do mesmo. O Primeiro passo é instalar o produto, esta parte vou pular devido a sua simplicidade. Abra o LLBLGen Pro, clique em File , New Project. Você deve informar:

  • O nome do projeto
  • O criador
  • O local onde o projeto será criado
  • DataBase Driver, neste exemplo SQL Server 7/200/2005 Driver (SQLClient)
  • O nome do servidor, estou usando uma instancia do SQL 2005, versão Express
  • Informações de autenticação, neste exemplo utilizo autenticação integrada.
  • Em Elements to read from database Schema, para simplificar este primeiro exemplo, mantenho marcado apenas Tables

Após clicar em Create, é aberta a IDE do LLBLGen Pro. No project Explorer, localize Entities, clique com o botão direito e selecione Add New Entities Mapped On Tables From Catalog(s):

Na janela New Entities Found selecione todas as entidades e clique em Add to Project:

Agora todas as tabelas de seu banco foram incluídas como entidades, você pode verificá-las individualmente ou mesmo alterar propriedades:

Vamos agora fazer a geração do código, para isso selecione Projetct, Generate.
Você agora tem que definir algumas configurações antes de gerar o código:

  • Na guia General settings, Informe a linguagem (VB.NET ou C#);
  • A plataforma: Você pode escolher entre .NET 1.0, 1.1, CF.NET 1.0 ou 2.0;
  • O namespace raiz;
  • O Grupo de Modelo;
  • A pasta de destino.

Na guia template bindings você pode escolher a precedência entre os modelos de ligação

Na guia Task queue to execute você pode escolher entre um modelo Geral, ou um modelo com duas classes. O modelo com duas classes gera uma classe derivada de
cada Entidade, para que a regra de negócio possa ser escrita nesta. Eu pessoalmente prefiro o modelo Geral, e escrever a regra de negócio em novos arquivos criados manualmente com “classes partial”.

Tudo pronto, basta clicar em Start Generator e aguardar alguns segundos. O LLBLGen Pro gerou um projeto com algumas pastas e dezenas de arquivos. Abra o
projeto criado no VS 2005.


Examine a pasta EntityClasses, note que para cada Tabela foi gerado uma classe em um arquivo vb / cs distinto.
Primeiramente vou demonstrar alguns exemplos com uma aplicação console, para depois mostrar exemplos mais avançados de ligação de dados com controles visuais. Adicione uma aplicação Console de nome Teste, defina a solução com aplicativo inicial, adicione referencias ao projeto AdventureWorks e ao assembly SD.LLBLGen.Pro.OrmSupportClasses.NET20. Copie o arquivo app.config do projeto AdventureWorks para seu projeto console. Neste arquivo esta a string de conexão com o SGBD.


No Module1.vb / Program.cs adicione duas clausulas imports:

Vb.net:

Imports AdventureWorks.EntityClasses
Imports AdventureWorks.CollectionClasses

C#:

using AdventureWorks.EntityClasses;
using AdventureWorks.CollectionClasses;

Neste primeiro exemplo vamos exibir o primeiro e ultimo nome de um contato, que esta armazenado na tabela contato:

Vb.net:

Dim contato As New ContactEntity(1)
Console.WriteLine(contato.FirstName & " " & contato.LastName)
Console.ReadLine()

C#:


ContactEntity contato = new ContactEntity(1);
Console.WriteLine(contato.FirstName + " " + contato.LastName);
Console.ReadLine();

Roda e aplicação e Uauuuuu! Impressionante, sem abrir ou instanciar conexão,
sem digitar comando SQL, sem passar parâmetros, e o melhor, tudo com
Intellisense!!!


O código simplesmente instancia um contato pela sua chave ContactID, que é passado no construtor. Depois basta ler as propriedades.
Alterar um contato é da mesma forma simples:

VB.NET:

Dim contato As New ContactEntity(1)
contato.FirstName = "Fernando"
contato.Save()
Console.WriteLine(contato.FirstName)
Console.ReadLine()

C#:


ContactEntity contato = new ContactEntity(1);
contato.FirstName = "Fernando";
contato.Save();
Console.WriteLine(contato.FirstName);
Console.ReadLine();

Para inserir é utilizado o mesmo método, save. Na verdade o LLBLGen verifica o flag IsNew, para saber se deve ser feita uma inserção ou atualização:
Neste exemplo eu uso um construtor sem parâmetros, defino algumas propriedades, e chamo o método save.

VB. NET:

Dim contato As New ContactEntity()
contato.NameStyle = False
contato.FirstName = "Fernando"
contato.LastName = "Amaral"
contato.EmailPromotion = 1
contato.PasswordHash = "zh3goJUbYsPv92k4bVZuJtlLHwuvpQtu6uNcjkKSdF8="
contato.PasswordSalt = "rpyd5Tw="
contato.Save()
Console.ReadLine()

C#:

ContactEntity contato = new ContactEntity();
contato.NameStyle = false;
contato.FirstName = "Fernando";
contato.LastName = "Amaral";
contato.EmailPromotion = 1;
contato.PasswordHash = "zh3goJUbYsPv92k4bVZuJtlLHwuvpQtu6uNcjkKSdF8=";
contato.PasswordSalt = "rpyd5Tw=";
contato.Save();
Console.WriteLine(contato.FirstName);
Console.ReadLine();

Posso ainda, antes da inserção, verificar uma possível violação de chave primaria verificando a propriedades IsNew. Outra possibilidade é verificar se a inclusão foi
realizada, já que o método save retorna um valor Booleano indicando o sucesso da operação:

VB.NET:

Dim contato As New ContactEntity(1)
contato.NameStyle = False
contato.FirstName = "Fernando"
contato.LastName = "Amaral"
contato.EmailPromotion = 1
contato.PasswordHash = "zh3goJUbYsPv92k4bVZuJtlLHwuvpQtu6uNcjkKSdF8="
contato.PasswordSalt = "rpyd5Tw="
If Not contato.IsNew Then
Console.WriteLine("Já existe um contato com este código") 'A
Else
If contato.Save() Then 'B
Console.WriteLine("Registro gravado com sucesso!")
Else
Console.WriteLine("O registro não foi gravado")
End If 'C
End If
Console.ReadLine()

C#:

ContactEntity contato = new ContactEntity();
contato.NameStyle = false;
contato.FirstName = "Fernando";
contato.LastName = "Amaral";
contato.EmailPromotion = 1;
contato.PasswordHash = "zh3goJUbYsPv92k4bVZuJtlLHwuvpQtu6uNcjkKSdF8=";
contato.PasswordSalt = "rpyd5Tw=";
if (! contato.IsNew)
{
Console.WriteLine("Já existe um contato com este código");//A
}
else
{
if (contato.Save()) //B
{
Console.WriteLine("Registro gravado com sucesso!");
}
else
{
Console.WriteLine("O registro não foi gravado");
}//C
}
Console.ReadLine();

Note que no exemplo acima instanciamos um contato com o código 1. Se este registro já existir, será exibida uma mensagem no console. Observe também que,
se você trocar a linha marcada como A pelas linhas de B até C, o registro será atualizado já que a flag IsNew estará marcada como false.
Outro fator interessante é que o LLBLGen já cria os caminhos de relacionamento, tanto 1:n como n:1, ou seja, você pode percorrer um relacionamento em qualquer
direção. Por exemplo, um endereço (Address) possui um estado (CountryRegion). Podemos percorrer a caminho de relacionamento para obtermos o estado de
determinado endereço:

VB.NET

Dim endereco As New AddressEntity(1)
Console.WriteLine(endereco.StateProvince.Name)
Console.ReadLine()

C#:


AddressEntity endereco = new AddressEntity(1);
Console.Writeline(endereco.StateProvince.Name);
Console.ReadLine;

O caminho contrário também é possivel, podemos obter todos os endereços de um determinado estado, porém agora não é mais um relacionamento 1:n, e sim n:1. O
LLBLGen Pro, para toda classe criada para cada entidade, cria também uma classe Collection, que retorna uma coleção de uma determinada entidade.
Para obtermos todas as endereços que estão em determinado estado, podemos executar o seguinte código:

VB.NET:

Dim estados As New StateProvinceEntity(1)
Dim enderecos As New AddressCollection
enderecos = estados.GetMultiAddress(False)

C#:

StateProvinceEntity estados = new StateProvinceEntity(1);
AddressCollection enderecos = new AddressCollection();
enderecos = estados.GetMultiAddress(false);

Observe que o método GetMultAddress foi criado pelo LLBLGen na ocasião da
geração do código! Para todo relacionamento n:1 vai existir um método GetMulti
seguido pelo nome da Entidade. Este método retorna uma coleção do tipo da
entidade, por isso para recebê-lo instanciamos um tipo AddressCollection.
Podemos facilmente percorrer a coleção usando uma laço for...each:

VB.NET

Dim estados As New StateProvinceEntity(1)
Dim enderecos As New AddressCollection
enderecos = estados.GetMultiAddress(False)
Dim endereco As New AddressEntity
For Each endereco In enderecos
Console.WriteLine(endereco.AddressLine1)
Next
Console.ReadLine()

C#:


StateProvinceEntity estados = new StateProvinceEntity(1);
AddressCollection enderecos = new AddressCollection();
enderecos = estados.GetMultiAddress(false);
foreach (AddressEntity endereco in enderecos)
{
Console.WriteLine(endereco.AddressLine1);
}
Console.ReadLine();

Ligação com controles visuais: WebForm


Você pode facilmente ligar a instancia de seus objetos com controles visuais utilizando, por exemplo, um ObjectDataSource, porém o LBLGen Pro 2.0 traz
alguns controles de ligação. Vamos fazer uma experiência. Primeiramente com uma aplicação Web. Adicione uma projeto ASP.NET a sua
solução.


Inicialmente vamos adicionar os controles de ligação do LBLGen Pro a sua ToolBox:

Observe a caixa de ferramentas já com os controles:

O LLBLGenProDataSource deve ser utilizado se o Template utilizado na geração do código foi SelfServicing (Nosso caso) , e LLBLGenProDataSource2 se o modelo foi Adapter.


Agora adicione as referencias do projeto AdventureWorks e ao assembly SD.LLBLGen.Pro.OrmSupportClasses.NET20.
Arraste um controle LLBLGenProDataSource e um GridView a seu formulário. Configure o LLBLGenProDataSource através da SmartTag, em Container Type
mantenha EntityCollection e em Entity collection to select selecione AdventureWorks.CollectionClasses.CountryRegionCollection. Observe que neste ultimo item são listados todas as classes Collection criadas pelo LLBLGen Pro.

No GridView, em DataSourceID, selecione LLBLGenProDataSource1. Você pode ainda aplicar uma auto formatação para deixar o visual mais atraente.
Finalmente adicione a string de conexão ao web.config:

 

connectionStrings>
<add name="Main.ConnectionString" connectionString="data
source=Casa\SQLExpress;initial catalog=AdventureWorks;user
id=sa;password=123;packet size=4096"/>
</connectionStrings>

 

Rode a aplicação e aprecie o resultado.

Observe que você não digitou uma linha de código!


Conclusão

Estas poucas páginas mostraram algumas poucas funcionalidades desta poderosa ferramenta ORM, que com certeza faz se tornar rapidamente uma referencia no
desenvolvimento de aplicações .NET.

Últimos artigos relacionados:
Refatoração (Refactoring) em Visual Studio 2008
Medindo a Performance de seu Código com Visual Studio Team System 2008
Code Snippets no Visual Studio 2008
Análise de Código com Visual Studio Team System 2008
.NET independente de plataforma? Uma introdução ao Mono