You are on page 1of 32

maro 2009

maro 2009

ndice
Editorial
Posso dizer que a partir do ms de Agosto do ano passado onde assumi a direo da revista The Club Megazine, todas nossas edies foram feitas com o objetivo de levar um contedo cheio de novidades ...

Delphi
DataSnap 2009 - ParteI Introduo Zlib - Construndo um compactador de arquivos no Delphi Aprimorando o desempenho de um Banco de Dados Delphi Prism com LINQ

04

05 10 13 15

.NET
Trabalhando com dynamic Data Controls
O ASP.NET ultimamente vem revolucionou o desenvolvimento de aplicaes para web oferecendo uma plataforma robusta e altamente produtiva elevando o potencial dos desenvolvedores com excelente recursos como: GridView, DataControls, Validators , WebParts entre outros.

Dicas Delphi
Ativar Auto Run do CD-ROM Criptografar Strings Ver se existe Midia no Drive Ver impressora conectada Localizar Arquivos no Windows Mostrar as fontes True Types instaladas no Windows

24

28 30
03

Legenda
Iniciante Intermedirio Avanado
maro 2009

Desafio The CLub


Teste seus conhecimentos.

Bem-vindo
Posso dizer que a partir do ms de Agosto do ano passado onde assumi a direo da revista The Club Megazine, todas nossas edies foram feitas com o objetivo de levar um contedo cheio de novidades e recursos aplicveis no dia-a-dia do programador. Este ms nos do The Club ficamos muito satisfeitos com o resultado desta edio, pois acreditamos que nas paginas desta edio para qualquer que seja o leitor, com certeza novidades sero encontradas. Assim continuando a seqncia de artigos sobre a nova ferramenta da Embarcadero, o Delphi Prism, Luiz Alexandre com seu artigo Delphi Prism com Linq (Language Integrate Query), nos mostras mais algumas funcionalidades da ferramenta num artigo bastante completo que apresenta conceitos do Linq, que podem ser aplicados inclusive em um aplicao C#. Sabemos da importncia de velocidade e performance em nossas aplicaes, desta forma o consultor Marco Antonio Armando em seu artigo Aprimorando desempenho de banco de dados, demonstra em dicas simples, mas de grande importncia na aplicao, como escrever consultas SQL visando obter a melhor eficincia do banco de dados. Entre as muitas novidades apresentadas pela Embarcadero no lanamento do Delphi 2009, encontramos os novos avanos na tecnologia DataSnap que chamaram bastante a ateno, neste ms trago o artigo DataSnap 2009 - Introduao onde mostro como ficou simples e funcional criar um servidor de mtodos DataSnap, mostrando o poder de uma tecnologia que embora lanadas a muito tempo ainda uma grande caixa preta para muitos programadores, e que agora aps um perodo de estagnao da tecnologia, foi remodelada pela Embarcadero sendo lanada nesta nova verso com novos recursos e independente da tecnologia COM. Uma necessidade comum nas aplicaes a compactao de arquivo seja para backup de dados ou envio de arquivo pela internet, assim o consulto Antonio Spitaleri escreveu o artigo Zlib Construindo um compactador de Arquivos no Delphi onde usando a Unit ZLib.pas nativa do Delphi demonstra como realizar este procedimento sem o uso de nenhum componente de terceiros. Ao longo dos anos surgiu no mercado necessidades como a criao de telas automticas de cadastro, com o lanamento do Service Pack 1 do .NET 3.5, foi disponibilizando dentro do ASP.NET um novo conjunto de controles conhecido como Dynamic Data Controls que tem objetivo de montar as telas para as aes bsicas. Assim este ms Fabiano Belmont aborda este assunto com seu novo artigo Trabalhando com Dynamic Data Controls. Que todos tenham uma boa leitura e apreciem os artigos sem moderao.
Marcos Csar Silva - Editor Chefe marcos@theclub.com.br
04
maro 2009
Av. Prof Celso Ferreira da Silva, 190 Jd. Europa - Avar - SP - CEP 18.707-150 Informaes: (14) 3732-1529 Suporte: (14) 3733-1588 http://www.theclub.com.br Cadastro: cadastro@theclub.com.br Suporte: suporte@theclub.com.br Informaes: info@theclub.com.br Skype Cadastro: theclub_cadastro Skype Suporte: theclub_linha1 theclub_linha2

Internet

Copyright The Club Megazine 2008 Diretor Tcnico Marcos Csar Silva Diagramao e Arte Vitor M. Rodrigues Reviso Marcos Csar Silva Colunistas Antonio Spitaleri Neto Fabiano Belmonte Lus Alexandre de Oliveira Marco Antonio Armando Marcos Csar Silva

Impresso e acabamento:
GRIL - Grfica e Editora Rua So Paulo, n 447 Cep: 18740-00 - Taquarituba-SP Tel. (14) 3762-1345
Reproduo
A utilizao, reproduo, apropriao, armazenamento em banco de dados, sob qualquer forma ou meio, de textos, fotos e outras criaes intelectuais em cada publicao da revista The Club Megazine so terminantemente proibidos sem autorizao escrita dos titulares dos direitos autorais.

Delphi marca registrada da Borland International, as demais marcas citadas so registradas pelos seus respectivos proprietrios.

Delphi

Parte I
Entre as muitas novidades apresentadas pela Embarcadero no lanamento do Delphi 2009, encontramos os novos avanos na tecnologia DataSnap que chamaram bastante a ateno. O DataSnap embora possa parecer uma tecnologia nova e cheia de mistrios nasceu juntamente com o lanamento do Delphi 3, inicialmente conhecida como tecnologia MIDAS ( Multi-Tier Distributed Application Services), teve seu nome alterado para Datasnap quando no lanamento do Delphi 6 passou a contar com suporte a SOAP/XML HTTP. Um dos principais avanos concebido nesta nova verso foi desvinculao do Datasnap da tecnologia COM, independncia esta esperada a logo prazo por muitos desenvolvedores que ira simplificar em muito o processo de desenvolvimento. Embora que vale ressaltar que foi mantida toda compatibilidade com verses anteriores.

Introduo

Imagem 1 Criando VCL Forms Applications

pelo servidor.

Criao do Servidor Datasnap


No RAD Studio Delphi 2009 para criar uma aplicao servidora Datasnap o primeiro passo criar uma aplicao VCL Forms Applications comumente utilizada, para isto v em New Projects selecione a

este artigo ire demonstrar com criar um servidor de mtodos e uma aplicao cliente que ir consumir os mtodos disponveis

opo VCL Forms Applications (Imagem 1). Ser criado a unit principal que salvaremos com o nome de unServer.pas e o projeto que salvaremos como Server.dpr, iremos tambm alterar a propriedade Name do form criado frmServer. Veja a imagem 1.
maro 2009

05

Neste momento irei adicionar os componentes servidor Datasnap, para isto em Tool Palette selecione a opo DataSnap Server e inseria no formulrio os componente TDSServer, TDSTCPServerTransport e um TDSServerClass1 como pode ver na Imagem 2.

Imagens 2 Componentes Inseridos no formulrio

Imagem 3 Criando o Server Module

Uma vez inserido os componentes necessrio configurar a propriedade Server dos componentes DSTCPServerTransport 1 e DSServerClass11 para DSServer1. Uma dica importante neste momento observar a propriedade Port que se encontrada no componente TDSTCPServerTransport, o numero da porta dever ser nico por aplicao servidora para evitar que mais de uma aplicao responda na mesma Porta.
06
maro 2009

Criaremos agora o Server Module, que ser nosso DataModule da aplicao DataSnap, ou melhor um TProviderDataModule que ira servir como um provedor de mtodos e dados da aplicao Servidora. Para criar o Server Module v em New Itens e selecione o item Server Module (Imagem 3), e salve-o como unServerModule;

Veja a imagem 3. Apenas para finalidade de demonstrao irei criar um mtodo que ir retorna a verso do projeto, para isto no cdigo fonte do TDSServerModule1, na seo public da classe declare a function PegaVersao e em implementation insira o cdigo fonte da funo como pode ver abaixo:

type TDSServerModule1 = class(TDSServerModule) private { Private declarations } public function PegaVersao:string; end; var DSServerModule1: TDSServerModule1; implementation {$R *.dfm} { TDSServerModule1 } function TDSServerModule1. PegaVersao: string; begin Result := Verso 1.0; end;

Agora voltaremos ao form frmServer e adicione a uses unServerModule com Alt+F11 (Imagem 4) e no componente DSServerClass1, adicione o evento OnGetClass e insira o cdigo abaixo:

var PersistentClass: TPersistentClass); begin PersistentClass := TDSServerModule1 end;

procedure TfrmServer. DSServerClass1GetCl ass(DSServerClass: TDSServerClass;

maro 2009

07

e ento ser executado o mtodo desejado da classe, que neste caso o PegaVersao;

implementation uses unClientClass; {$R *.dfm} procedure TfrmClient. Button1Click(Sender: TObject); var ServerModule: TDSServerModule1Client; Imagem 4 - Adicionando a uses unServerModule Imagem 5 Propriedades do SQLConnection1 begin ServerModule := TDSServerModule1Client. Create(SQLConnection1. DBXConnection); try Label1.Caption := ServerModule.PegaVersao; finally ServerModule.Free; end; end;

Compile o projeto com a opo Run Without Debugging Shift+Ctrl+ F9 assim ser criado o executvel Server.exe sem a opo de debug, no prendendo a sua execuo com a IDE do Delphi, neste momento apenas minimize o executvel do projeto servidor, pois o mesmo dever estar em execuo para responder ao projeto cliente que iremos criar.

Agora Clique com o boto direito no mouse sobre o componente SQLConnection1 e selecione a opo Generate DataSnap client classes (Imagem 6), para que seja criado pelo DataSnap proxy generator a unit de classes cliente correspondente ao mtodos disponveis na aplicao servidora, salve-a como unClientClass.pas. Outra dica importante, certifique-se que a aplicao servidora esta rodando, caso contrrio a classe no ser gerada com sucesso.

Criao do Cliente DataSnap


O prximo passo antes de criar a aplicao cliente e salver o grupo de projetos em Project Manager, para isto clique com o boto direito do Mouse sobre o Arquivo de Grupo de projetos e selecione Save Projet Group As salve como DataSnapProjectGroup.groupproj, salvo o arquivo volte a clicar sobre o Grupo de Projetos e selecione Add New Project selecione a opo VCL Forms Applications para criarmos a aplicao cliente, salve a unit como unClient.pas renomeando a propriedade Name do formulrio para frmClient, e salvando o projeto como Client.dproj. O prximo passo adicionar os componentes de conexo, para isto em Tool Palette selecione o componente TSQLConnection e adicione no formulrio frmClient, assim no SQLConnection1 em sua propriedade Driver selecione o item Datasnap, observe que esta propriedade no Object Inspector tem Subpropriedades , coloque na subpropriedade HostName o valor localhost e em port 211, e no esquea de alterar a propriedade LoginPrompt para false como pode var na imagem 5

Variao da Aplicao Cliente DataSnap


Para deixarmos mais evidente que a conexo est sendo feita atravs do driver DBXClient existindo uma integrao direita com DataSnap e dbExpress, iremos utilizar a mesma funo da aplicao Server, s que desta vez sem a declarao da classe TDSServerModule1Client como foi feito no processo anterior. Para isto adicione o componente TSqlServerMethod que se encontra em Tool Palette -> dbExpress no formulrio frmClient, altere a sua propriedade SQLConnection para SQLConnection1 e em ServerMethodName observe que ser listada todos os mtodos da aplicao Server, selecione assim o item que nos interessa que o TDSServerModule1.PegaVersao (Imagem 6). Adicione mais um componente TLabel e outro TButton, no evento Onclick deste novo boto coloque o cdigo abaixo responsvel por executar o mtodo:

Imagem 6 Criando as classes cliente

Para que possamos testar, adicione no form frmClient a uses unClientClass (Alt+F11) e coloque um componente Label para receber o retorno do mtodo e um Button para disparar a execuo, no evento OnClick do boto adicione o cdigo que pode ver abaixo, para que desta forma quando for executado o clique no boto ser criado a classe TDSServerModule1Client gerada na etapa anterior

procedure TfrmClient. Button2Click(Sender: TObject);

08

maro 2009

acesso a banco de dados.


begin SqlServerMethod1. ExecuteMethod; Label2.Caption := SqlServerMethod1. ParamByName (ReturnParameter). AsString; end;

Quando selecionamos o ServerMethodName no componente SqlServerMethod1, automaticamente a propriedade params deste componente foi preenchida, neste nosso caso existia apenas o parmetro de retorno (Result) chamado por padro como ReturnParameter, Caso nosso mtodo tivesse parmetros de entrada (Imput), estes parmetros seriam tambm adicionados em Params, e deveriam ter uma valor para eles atribudos antes da chamada do mtodo ExecuteMethod do componente SqlServerMethod1 da seguinte forma:

Download:
www.theclub.com.br/revista/rev0309/datasnap2009.rar

Referencia:
http://blogs.embarcadero.com/ andreanolanusse/2008/10/16/exemplos-datasnap-dbexpress-e-outros-recursos-do-delphi2009/

SqlServerMethod1. ParamByName(Parametro1). AsInteger := 10;

Sobre o autor
Marcos Csar Silva, Consultor de Sistemas na consultoria de sistemas DataSmart e Consultor Tcnico do The Club, Bacharel em Cincia da Computao, MBA em Gesto Empresarial, Certificaes MCAD (Microsoft Certified Application Developer) e MCSD.NET (Microsoft Certified Solution Developer .NET)

Concluso
Vimos como ficou muito mais simples e prtico a criao de aplicao Multicamadas, no dependendo de nenhuma outra tecnologia para seu funcionamento. Em nosso prximo encontro iremos ver como usar a tecnologia Datasnap para

Imagem 7 Selecionado o mtodo

maro 2009

09

Entre as inmeras units presentes no Delphi, sem dvida uma que poucos conhecem a zlib. Essa unit contm classes que tornam possvel a criao de objetos que realizam a compactao de arquivos. Nesse artigo, estarei mostrando passo a passo com construir um compactador de arquivos bem simples utilizando Delphi e a zlib. Mos a obra!

Formulrio:frmcompactador. Edits: edtarquivo,edtdestino. Buttons: btncompacta,btndescompacta,btnse lecionaarq,btndestino; Finalizando, insira ao lado das edits edtarquivo e edtdestino duas labels com as propriedades caption como arquivo e destino respectivamente. O formulrio dever ficar com a seguinte aparncia: Veja a Figura 01.

evento onclick do btnselecionaarq digite:

procedure Tfrmcompactador. btnselecionaarqClick(Sender: TObject); begin OpenDialog1.Execute; edtarquivo. Text:=OpenDialog1.FileName; end;

Preparando a Aplicao
Inicie um novo projeto no Delphi, e inclua na unit do form a unit zlib. Insiram no formulrio os seguintes componentes: 2 edits(palheta standard); 4 buttons(palheta standard); 2 labels(palheta standard); 1 opendialog(palheta dialogs); Altere as propriedades name dos componentes conforme segue:

Realizando a codificao
Chegou a hora de inserirmos o cdigo necessrio para que o nosso compactador funcione.No

Nesse evento estamos abrindo a caixa de dilogo abrir do windows, selecionando um arquivo e colocando seu caminho na edtarquivo. No evento onclick do btndestino digite:

Figura 01. 10
maro 2009

procedure Tfrmcompactador. btndestinoClick(Sender: TObject); begin OpenDialog1.Execute; edtdestino.Text:=Extra ctFilePath(OpenDialog1. FileName); end;

Aqui estamos selecionando um arquivo e extraindo atravs da funo extractfilepath seu caminho j que apenas o caminho que ser utilizado.Esse caminho ir ser exibido na edtdestino. Agora a parte mais importante, que a codificao que ir realizar a compactao do arquivo selecionado. nessa parte que estaremos utilizando as classes da zlib que realizam a compactao. No evento onclick do btncompacta digite:

procedure Tfrmcompactador. btncompactaClick(Sender: TObject); var FileIni, FileOut: TFileStream; Zip: TCompressionStream; nomearq:string; begin try try nomearq:=InputBox(C ompactar,Digite um nome para o arquivo,); FileIni:=TFileStream. Create(edtarquivo. Text, fmOpenRead and fmShareExclusive); FileOut:=TFileStream. Create(nomearq+. zip, fmCreate or fmShareExclusive);

Zip:=TCompressionStream. Create(clMax, FileOut); Zip.CopyFrom(FileIni, FileIni.Size); except Raise Exception. Create(No foi possvel compactar o arquivo); abort; end; finally Zip.Free; FileOut.Free; FileIni.Free; end; end;

Fileini recebe o arquivo a ser compactado no formato stream para ser processado pelo objeto zip, que realiza a compresso e coloca o resultado no objeto fileout, este ltimo tambm do tipo tfilestream.

maro 2009

11

DeZip:=TDecompressionStream. Create(FileIni); repeat i:=DeZip.Read(Buf, SizeOf(Buf)); if i <> 0 then FileOut. Write(Buf, i); until i <= 0; except raise Exception. Create(No foi possvel descompactar o arquivo); abort; end; finally DeZip.Free; FileOut.Free; FileIni.Free; end; end;

Repare que essa rotina possui a varivel buf, um array de 1024 bytes onde ser escrito o resultado da descompresso. Repare que caso algum erro ocorra, o processo de compresso interrompido e enviada uma mensagem ao usurio de que a compresso no foi possvel. A chamada funo inputbox no incio do evento permite que o usurio escolha o nome desejado para o arquivo depois de compactado. Os arquivos compactados com a unit zlib possuem a extenso .zip que uma das extenses de arquivos compactados mais utilizada atualmente. O objeto mais importante de nosso aplicativo o zip, do tipo tcompressionstream.A classe tcompressionstream da unit zlib que contm os cdigos que permitem a compresso de arquivos. Alm da classe Tcompressionstream, a zlib tambm possui a classe tdecompressionstream, que como o nome sugere, realiza a descompresso de arquivos. Apesar de no ser o foco do artigo, estarei mostrando um pequeno exemplo de cdigo para descompactao que pode ser inserido no evento onclick do btndescompacta:
12
maro 2009

procedure Tfrmcompactador. btndescompactaClick(Sender: TObject); var FileIni, FileOut: TFileStream; DeZip: TDecompressionStream; i: Integer; Buf: array[0..1023]of Byte; nomearq:string; begin try try nomearq:=InputBox (Descompactar,Digit e um nome e a extenso do arquivo,); FileIni:=TFileStream. Create(edtarquivo. Text, fmOpenRead and fmShareExclusive); FileOut:=TFileStream. Create(nomearq,fmCreate or fmShareExclusive);

Na rotina de descompresso, a inputbox dever ser preenchida com o nome e a extenso do arquivo. Ex:teste.txt.Diferentemente da compresso onde apenas o nome necessrio. Como pde ser observado, com a unit zlib possvel construir um compactador de arquivos at com certa facilidade sem a necessidade de componentes de terceiros.

Espero que tenham gostado e at a prxima.

Sobre o autor
Antonio Spitaleri Neto
Consultor Tcnico The club antonio@theclub.com.br

APRIMORANDO O DESEMPENHO DE UM BANCO DE DADOS


No dia a dia, uma preocupao para desenvolvedores de bancos de dados, sem sombra de dvidas, a performance final dos mesmos. Neste sentido, muitos programadores se confundem no que tange a diferena entre um ajuste de banco de dados versus ajuste de uma instruo SQL.

Ajuste de uma instruo SQL


O ajuste de uma instruo SQL, visa construir instrues com excelncia, visando obter resultados com eficcia. A formatao de uma instruo representa um papel crucial na performance final, neste contexto o ajuste da clausulas FROM E WHERE so vitais, pois so essas duas clausulas das quais dependero a forma em que o servidor de bancos dados ir process-la. Embora possa ser rotineiro em nosso cotidiano, a construo de instrues SQLs, requer ateno, e alguns pr requisitos fundamentais, eis alguns deles: Levar em conta sempre a legibilidade; Posicionamento das tabelas na clusula FROM; Posicionamento de condies restritivas na clusula WHERE; Posicionamento de condies de JOIN na clusula WHERE;

LEGIBILIDADE
Quando se pensa em ajuste de uma instruo SQL, o primeiro passo a se levar em conta a legibilidade da mesma, a fim de que fique bem escrita, e facilite a vida de quem alm do desenvolvedor que a escreveu, possa discerni-la de forma rpida e segura. Para isto relacionaremos abaixo algumas particularidades que tornam uma instruo de forma legvel: Inserir uma clusula FROM em uma linha separada da clusula SELECT, e clusula WHERE separada da clusula FROM:

Assim desmistificando, temos: O ajuste de um banco de dados significa o processo de ajustar o banco de dados real, ou seja, fatores como: alocao de memria, uso de disco, CPU, etc. No podemos nos esquecer tambm que o ajuste tambm compreende a estrutura do banco de dados, como tabelas e ndices. O ajuste de uma instruo SQL, o processo ajustar uma instruo SQL, como consultas, inseres, etc., com o objetivo de tirar o mximo proveito possvel em performance e confiabilidade.

SELECT ID_CODIGO, NOME, CPF FROM CLIENTES WHERE NOME = GILSON

O uso de tabulaes ou espaos e recomendvel quando um argumento de uma clusula, excedem uma linha.
maro 2009

13

Quando da necessidade de utilizar vrias tabelas em uma instruo, o uso de aliases indispensvel.

SELECT C.ID_CODIGO, C.NOME, V.ID_CODIGO, V.VALOR FROM CLIENTES C, VENDAS V

FROM CLIENTES C, PEDIDOS P WHERE C.ID_CODIGO = P.ID_ CODIGO AND C.CIDADE = SAO PAULO AND P.VALOR > 100

ltimo, pois a primeira condio que lida pelo otimizador do banco utilizado. Abaixo vejamos a sintaxe bsica:

Inicie sempre uma nova linha na instruo, caso haja a necessidade de se trabalhar com vrias colunas na instruo SELECT, isto tambm se aplica as clusulas FROM e WHERE.

Podemos observar que as duas instrues retornaram o mesmo nmero de registros, e no tero nenhuma diferena na sua performance, mas para quem as lerem, far uma grande diferena, principalmente se estivermos desenvolvendo um projeto de grande porte, que envolvam muitos desenvolvedores.

SELECT C.ID_CODIGO, C.NOME, C.CPF, C.TELEFONE, V.ID_CODIGO, V.VALOR, FROM CLIENTES C, VENDAS V WHERE C.ID_CODIGO = V.ID_CODIGO

ORDEM ADEQUADA DE CONDIES DE JUNO:


Quando trabalhamos com mais de duas tabelas em uma instruo SQL, a tabela base dever locada no lado direito de uma juno numa clusula WHERE, onde a unio dever ser feita sempre primeiramente com a menor tabela e posteriormente dever ser efetuada com as maiores, vejamos melhor no exemplo abaixo:

FROM TABELA1 <TABELA MENOR> TABELA2 TABELA3 <TABELA MAIOR> WHERE TABELA1.<COLUNA> = TABELA3.<COLUNA> AND TABELA2.<COLUNA> = TABELA3.<COLUNA> AND CONDIO 1 <MENOS RESTRITIVA> AND CONDIO 2 <MAIS RESTRITIVA>

Veremos abaixo, um exemplo clssico de como muitos desenvolvedores escrevem uma instruo SQL, onde no se leva em conta a legibilidade:

SELECT C.ID_CODIGO, C.NOME, C.CPF, C.TELEFONE, C.CIDADE, P.ID_CODIGO, P.NUM_PEDIDO, P.VALOR, P.QTDE FROM CLIENTES C, PEDIDOS P WHERE C.ID_CODIGO = P.ID_ CODIGO AND C.CIDADE = SAO PAULO AND P.VALOR > 100

SELECT <COLUNAS> FROM TABELA1 (TABELA MENOR) TABELA2 TABELA3 (TABELA MAIOR) WHERE TABELA1.<COLUNA> = TABELA3.<COLUNA> TABELA2.<COLUNA> = TABELA3.<COLUNA>

Se por ventura, na implementao utilizada, na sua documentao, no mencionar como o otimizador funciona quanto a condies de restrio, para que possamos escrever instrues que interajam de maneira mais eficiente com o banco de dados, a melhor forma, seria executar as consultas cronometrando o seu tempo de execuo, verificando se o otimizar l a clusula WHERE, de cima para baixo, ou de baixo para cima. Posteriormente, devemos organiz-las de forma que as condies restritivas respondam de maneira concernente ao otimizador. muito comum, no suporte do THE CLUB, os scios muitas vezes, apresentarem muita preocupao e dvidas quanto a conexo a ser escolhida para desenvolvimento de uma aplicao, isto sem dvida requer uma escolha correta, mas nunca no podemos de nos esquecer que, banco de dados bem construdos, e instrues SQLs bem escritas nos pouparo de muitos problemas, e nos retornaro, um resultado final muito mais proveitoso, principalmente aos olhos de nossos clientes. Um abrao e at a prxima.

BUSCANDO A CONDIO RESTRITIVA


Buscar a condio mais restritiva o foco principal, visando um timo desempenho em uma consulta SQL. Assim podemos definir uma condio restritiva, como a forma de utilizarmos em uma clusula WHERE de uma instruo que retorne uma menor quantidade de registros. Para isto importante saber como o otimizador do banco de dados opera para executar a instruo, pois alguns banco por exemplo lem da parte inferior da clusula WHERE para cima, assim devemos colocar a condio mais restritiva por

Agora levando em conta os princpios da legibilidade, vamos reescrever a instruo acima:

SELECT C.ID_CODIGO, C.NOME, C.CPF, C.TELEFONE, C.CIDADE, P.ID_CODIGO, P.NUM_PEDIDO, P.VALOR, P.QTDE 14
maro 2009

Sobre o autor
Marco Antonio Armando Consultor Tcnico The club

Todos os aplicativos, exceto os triviais, precisam processar dados. Historicamente, a maioria dos aplicativos fornece um lgica prpria para realizar essas operaes. Mas essa estratgia pode fazer o cdigo em um aplicativo tornar-se excessivamente amarrado estrutura dos dados que ele processa. E se houver mudanas no esquema de banco de dados, talvez voc necessite realizar um nmero significativo de alteraes no cdigo que trata os dados. A proposta da LINQ abstrair o mecanismo que um aplicativo utiliza para consultar dados a partir do prprio cdigo do aplicativo.

A LINQ fornece uma sintaxe e semntica muito semelhantes da SQL, com vantagens parecidas. Voc pode mudar a estrutura dos dados em consulta sem precisar alterar o cdigo que a realiza. A LINQ tem como objetivo simplificar consultas a informaes em collections, arrays, assim como informaes baseadas em base de dados, XML e objetos. Atualmente o LINQ suporta Linq to objects Linq to SQL Linq to xml

O diagrama acima apresenta uma viso geral do LINQ , seus provedores e as fontes de dados acessveis: LINQ TO OBJECTS
Tem como objetivo simplificar consultas a informaes em collections, arrays, assim como informaes baseadas em base de dados, XML e objetos Atualmente o LINQ suporta: LINQ to Objects LINQ to SQL LINQ to XML

Delphi Prism suporta LINQ atravs de : Sequences e Query Expressions Lambda Expressions Expressions Trees Extension Methods Anonymous Types Type Inference

Vamos entender como funciona o LINQ

QUERY EXPRESSIONS
maro 2009

15

Permite executar querys em coleo de objetos. Vamos contruir um exemplo prtico. V no menu File --> New --> Project . No treeview a esquerda escolha Delphi Prism. Selecione o template Windows Aplication .(Imagem 1) Clique em ok. No form Principal adicione um button e um listbox. Seu layout ficar assim (Imagem 2): Clique duas vezes no boto do formulrio. Adicione no evento do boto o seguinte trecho de cdigo (trecho 1)

method MainForm.btnok_ Click(sender: System. Object; e: System. EventArgs); begin var words : Array of string :=[ola,Delphi Prism, linq,The Club,Alexandre]; var shortwords:= From word in words where Word.Length<=5 Imagem 1

select Word;

for each word in shortwords do begin lstValor.Items. Add(word); end; end; Trecho1. Imagem 2

Na edio anterior, abordei algumas caracteristicas da linguagem Oxygene( baseado em Object Pascal), vale a pena dar uma olhada. Observe a nova sintaxe de declarao de variveis. Declarei um array com 5 elementos. Na varivel shortwords (Query Exprressions) fiz um select dentro do array para trazer as palavras que contenham at 5 caracteres. Observe que a varivel word receber os itens consultados. Um ponto importante que essa varivel no necessita de uma declarao explicita e a mesma ser utilizada no escopo do select. O select word retorna a instncia do tipo array.
16
maro 2009

O lao de repetio for each traz o resultado do Query Expressions.D um F5 para debugar e observe o resultado na figura 3.

LINQ TO SQL
Permite executar querys em banco de dados, mapeando tabelas como classes, conhecidas como Entity classes. Tem como objetivo mapear tabelas e seus atributos como classes aproveitando o conheci-

Imagem 3

mento em SQL Vamos efetuar o mapeamento objeto relacional, criar um contexto de dados (DataContext) e consultar um banco de dados SQL Server com LINQ To SQL via cdigo .

Mapeando classes para Tabelas


O conceito de mapeamento objeto Relacional (ORM) no uma novidade. Um ORM pode ser visto como um classe (entidade) que possui propriedades ou campos que mapeiam para as colunas de um banco de dados. O mapeamento para uma tabela possui dois elementos bsicos: 1. TableAttribute - mapeia a classe para a tabela no banco de dados; 2. ColumnAttribute - mapeia cada propriedade para uma coluna do banco de dados; Para mapear a classe para uma tabela usamos o TableAttribute com argumentos nomeados para associar a classe com a tabela. Abra o Visual Studio 2008 e crie um novo projeto do tipo Windows Application com o nome ExemploLInq. A seguir inclua uma referncia ao LINQ To SQL clicando com o boto direito sobre o nome do projeto e selecionando Add Reference; A seguir na janela Add Reference selecione, na aba .NET, System.Data.Linq e clique no boto OK. Veja a imagem 4; Com isso j temos tudo pronto para iniciar o projeto. Vamos criar um banco de dados com o Studio Express. No object Explorer clique duas vezes em seucomputador\sqlexpress. Com o boto direito do mouse em DataBase, acesse new DataBase. Em databaseName coloque Categorias. Clique em OK e pronto,nosso banco j esta criado. Veja a imagem 5.
Imagem 5
maro 2009

Imagem 4

17

Clique duas vezes em CATEGORIAS e clique com o boto direito do mouse em tables. Adicione a primeira tabela conforme imagem 6 Faa o mesmo procedimento para adicionar a table SUBCATEGORIA. Veja a imagem 7. Faa o mesmo procedimento para criar uma tabela de contatos Vamos criar o diagrama do banco de dados. Clique em DataBase Diagrams com o boto direito do mouse e adicione um novo. Nosso relacionamento ficar assim: Veja a imagem 8. Nosso objetivo ser efetuar o mapeamento objeto relacional com as tabelas Contato Categoria e Subcategoria . No menu Project | Add New Item selecione o template Class e informe o nome Categoria.PAS. Clique em add. Nesta classe iremos definir o mapeamento entre as tabelas do banco de dados. Abra a classe e inclua a seguinte declarao :
Imagem 6.

System.Data.linq, System.Data.Linq.Mapping,

Agora inclua o seguinte cdigo(Listagem1) que ir criar o mapeamento para as tabelas Categorias e SubCategorias para os campos definidos:
Imagem 7. namespace ExemploLInq; interface uses System.Collections. Generic, System.Linq, System.Data.linq, System.Data.Linq.Mapping, System.Text; type [Table(Name:= 18
maro 2009

Imagem 8.

CATEGORIAS)] Categorias = public class Public [Column(IsPrimaryKey:=true, Name:=CATEGORIAID)] Property CategoriaID:Integer; [Column(Name:=NOME)] Property CatNome:String; End; [Table(Name := SUBCATEGORIAS)] Subcategorias = class Public [Column(IsPrimaryKey:=true, Name:=SUBCATEGORIAID)] Property SubcategoriaID:Integer; [Column(Name:=NOME)] Property SubcatNome:String; [Column(Name:=CATEGORIAID)] property CategoriaID:Integer; [Association (OtherKey:=CategoriaID)] Property Categorias: EntitySet<Categorias>; End; implementation end.

System.Linq, System.Data.linq, System.Data.Linq. Mapping, System.Text; type [Table(Name:= CONTATOS)] Contatos = Class Public [Column(IsPrimaryKey:=true, Name:=CONTATOID)] Property contatoid:Integer; [Column(Name:=Nome)] Property ContatoNome:String; End; implementation end.

No evento Clique do boto Query com Joins adicione o script abaixo: Adicione em uses System.Data.Linq,

Na classe principal Main.pas adicione um DataGridView que se encontra na seo Data do ToolBox. Adicione tambm dois buttons e um textbox que se encontra na seo Common Controls. O textbox ter o caminho do banco. Adicione em uses :

System.Linq, System.Data.Linq, System.Data.Linq. Mapping,

method MainForm.Joins_ Click(sender: System.Object; e: System.EventArgs); var Path :String := System.IO.Path. GetFullPath(tbDataBase. text); // inicializao da varivel para pegar o banco de dados db:DataContext := new DataContext(path); cats:Table<Categorias> := db.GetTable<Categorias>(); subcats:Table<Sub categorias>:=db. GetTable<Subcategorias>(); Begin Var query:= from cat in cats join subcat in subcats on cat. CategoriaID equals subcat. CategoriaID order by cat.CatNome select new class (cat.CatNome,subcat. SubcatNome);

Se trabalharmos com join podemos represent-las atravs de Associaes . ENTIDADES PODEM ESTAR RELACIONADOS ATRAVS DO ATRIBUTO DE ASSOCIAO (Joins) Observe que z classe que verifica a associao entre Subcategorias e Categorias de um produto. Vamos mapear a tabela contatos.Crie uma outra classe Contatos .Listagem 1

dataGridView1.DataSource := query; end;

O formulrio ficar assim:

namespace ExemploLInq; interface uses System.Collections. Generic,

Temos quatro variveis,sendo a primeira armazenado o caminho do banco e a segunda armazenda um DataContext que faz a conexo com o banco . As varaveis categoria e subcategoria so do tipo table e atravs do mtodo getTable elas referenciam seu tipo genrico. Em query temos os alias categoria e subcategoria representando as variaveis categorias e subcategorias respectivamente. Em on categoria.CategoriaID equals subcategoria.CategoriaID feito o join. Os registros so ordenados em order by Categoria.Nome.
maro 2009

19

O resultado retornado numa nova classe ( select new class (categoria.Nome,subcategoria. Nome) Atribuimos o resultado query que um collection em um DataGridView.

Nota do consultor.
A classe DataContext uma classe LINQ to SQL que atua como uma ponte entre o banco de dados SQL Server e as classes das entidades LINQ To SQL mapeadas para o banco de dados. Ela contm a informao e os mtodos para efetuar a conexo com o banco de dados e manipular os dados.
Imagem 9.

Da mesma forma , no boto query simples adicione o cdigo abaixo:

LINQ TO XML
method MainForm.Simples_ Click(sender: System. Object; e: System. EventArgs); Var Path :String := System.IO.Path. GetFullPath(tbDataBase. text); // inicializao da varivel para pegar o banco de dados db:DataContext := new DataContext(path); // Criao do Contexto begin Var contato:= from contato in db.GetTable<Contatos>() where contato.contatonome = JOSE select contato; dataGridView1.DataSource := contato; // atribuo a collection ao datasource end;

O LINQ to XML um provedor de dados LINQ que implementado no namespace System.Xml. LINQ a partir da verso 3.5 da plataforma .NET. Ele fornece um modelo de programao que permite ler, construir e escrever dados XML. Voc pode usar LINQ To XML para realizar consultas LINQ sobre dados no formato XML que podem ser retornados do arquivo de sistemas, de uma URL HTTP remota, de um web service ou partir de qualquer XML em memria existente. Observe a hierarquia da classe linq to XML. Veja a Imagem 9. As principais classes do link to xml so: XDocument Atua como um container para a rvore XML e deve ser usado somente se necessrio. Voc pode salvar o documento com um arquivo XML. XElement Permite criar elementos , modificar o contedo dos elementos (incluir, remover, modificar elementos filhos), modifica os atributos dos elementos , salvar como um arquivo XML. XAttribute Usado para criar um par nome/valor no interior de um elemento do arquivo XML. XName Representa um nome completo XML consistindo de um objeto XNamespace e do nome local.

XComment Representa um comentrio XML. XDocumentType Representa um documento XML DTD - Document Type Definition. XProcesingInstruction Representa o processamento de uma instruo de um documento XML. XTest Representa um n Texto. XDeclaration Representa uma declarao XML. O LINQ TO XML gera arquivos xml diretamente a partir das classes. Isso implica em reduo de linha de cdigo em at 4 vezes. Outro ponto importante que o XML at ento no tinha boa integrao com as linguagens, sendo necessrio o uso de diversas APIs. Vamos criar um pequeno exemplo desse poderoso recurso utilizando um array de livros. Crie um novo projeto em files->new projet windowapplication Adicione dois textbox e dois buttons. O layout ficar assim: Veja a Imagem 10 Para criar documentos completos XML voc deve primeiro instanciar o objeto XDocument e ento incluir o elemento XElement, XAtributte ou outra entidade que o documento necessita. Clique no boto gerar XML e adicione o cdigo abaixo

20

maro 2009

Imagem 10.

Var xml:System.Xml.Linq. XElement; begin xml:= new xElement(Clientes, new xElement(Cliente, new xAttribute(codigo,1), New XElement(nome, Alexandre), New XElement(email, meuemail@yahoo.com)), New XElement(cliente, New XAttribute(codigo, 2), New XElement(nome, Antonio), New XElement(email, antonio@bol.com.br))); textBox1.Text:= xml.ToString(); xml.Save(c:\ teste.xml); end;

O arquivo xml foi atribuido para o textbox1 . Foi utilizado o mtodo toString para converso de tipos. Um arquivo teste.xml foi gerado no diretrio raiz. No boto consultar xml adicione o cdigo abaixo.

var xml := XElement. Load(c:\teste.xml, LoadOptions.SetBaseUri or LoadOptions. SetLineInfo); begin var consulta := v in xml.Elements from

where v.Attribute(codigo). Value = 2 select v; For each cons in consulta do textBox2.Text:= cons.ToString; end;

Na varivel xml foi atribuido o contedo do arquivo teste.xml por intermdio da classe XElement. O LoadOption possui quatro opes . None : todas as linhas desnecessrias,linhas em branco e linhas de informaes, do arquivo XML no sero carregadas. PreserveWhitespace: essa opo define que todas as linhas em branco do arquivo XML
maro 2009

21

Imagem 11.

sero preservadas. SetBaseUri : essa opo define o preenchimento da propriedade BaseUri. SetLineInfo: essa opo habilita o preenchimento da das informaes de linha, essa informaes pode ser recuperadas atravs da interface IXmlLineInfo. Na varivel consulta atribumos os elementos do arquivos onde o atributo cdigo seja igual a 2. Observe o resultado da consulta. Veja a imagem 11.

Referncias:
http://www.microsoft.com/brasil/msdn/Tecnologias/arquitetura/LINQ.mspx http://msdn2.microsoft.com/en-us/netframework/aa904594.aspx http://msdn2.microsoft.com/en-us/vcsharp/aa336746.aspx http://weblogs.asp.net/scottgu/archive/2007/05/19/using-linq-to-sql-part-1.aspx http://blogs.embarcadero.com/pawelglowacki/2005/09/22/21244 http://blogs.teamb.com/craigstuntz/2007/03/28/33565/ http://msdn.microsoft.com/pt-br/library/system.xml.linq.aspx http://edn.embarcadero.com/br/article/39135 Microsoft Visual C# Passo a Passo - John Sharp

Concluso
Com esses exemplos d para se ter uma dia do poder do Linq para manipulao de objetos, consultas e de arquivos xml. A Linq promete, sobretudo ser uma nova forma de trabalho de dados em memria.

Sobre o autor
Lus Alexandre de Oliveira Tcnologo em Processamento de Dados ,graduado pela Faculdade de Tcnologia de Sorocaba, Consultor tcnico do The Club.
Docente do curso tcnico informtica - Etec de Avar e do curso Tecnologia em Redes de Computadores - Fatec Eduvale Avar 22
maro 2009

maro 2009

23

Trabalhando com Dynamic Data Controls

O ASP.NET ultimamente vem revolucionou o desenvolvimento de aplicaes para web oferecendo uma plataforma robusta e altamente produtiva elevando o potencial dos desenvolvedores com excelente recursos como: GridView, DataControls, Validators , WebParts entre outros.

Logo aps instalar o Service Pack 1 do Visual Studio 2008, vai aparecer, conforme apresentado na figura abaixo, mais um novo tipo de projeto web para o .NET 3.5 chamado de Dynamic Data Veja na imagem 1. Aps criar seu novo projeto, verifique nas referncias e vai observar que ele traz as os novos namespaces System.Web.DynamicData e System. Web.DynamicData.Design. A funcionalidade Dynamic Data Controls trabalha em conjunto com o LINQ TO SQL e Entities FrameWork, pois ele precisa de uma interface de acesso a dados que ser utilizada para gerar as funcionalidade em tempo de execuo.
Imagem 2.

o longo dos anos, outras necessidades foram surgindo no mercado como a criao de telas automticas de cadastro conhecidas atualmente como Scaffold bastante populares com o Ruby on Rails. J faz algum tempo que a Microsoft vem investindo em linguagens dinmicas e agora, com o lanamento do Service Pack 1 do .NET 3.5, foi disponibilizando dentro do ASP.NET um novo conjunto de controles conhecido como Dynamic Data Controls que tem objetivo de montar as telas para as aes bsicas de qualquer CRUD (Create, Read, Update, Delete).
24
maro 2009

Bem agora para continuarmos com o exemplo precisamos de uma base de dados e um diagrama LINQ que ser utilizado pela aplicao. Vou utilizar um banco de dados .mdb so SQLExpress que j tenho pronto. Veja a imagem 2.

Agora vou criar o Diagrama LINQ e adicionar as tabelas que desejo trabalhar em meu projeto, para isso basta clicar com o lado direto do mouse no projeto, selecionar a opo add new item, e selecionar o DataClasses.dbml do LINQ. Como na imagem abaixo. Veja a imagem 3.

Imagem 1.

Imagem 3.
maro 2009

25

Imagem 4.

Feito isso, agora vamos arrastar as tabelas que iremos utilizar no projeto para o diagrama do LINQ. Como na imagem abaixo. Agora vem a parte mais simples do projeto que ser a implementao propriamente dita, ou seja onde colocamos a mo na massa, mais fique tranqilo que com esta ferramenta trabalharemos muito pouco pois a idia e que tudo seja gerado em tempo de execuo. Para isso temos que configurar o Dynamic Data para utilizar o LINQ to SQL e gerar automaticamente as telas de manipulao das tabelas do diagrama. O primeiro lugar que vamos alterar e no arquivo global.asax nele devemos localizar o mtodo RegisterRoutes() e dentro do mesmo modifique a linha Model.RegisterContext adicionando o nome do diagrama gerado pelo LINQ que para o nosso exemplo que foi DataClassesDataContext alterando o valor de ScaffoldAllTables para true Veja a Imagem 5. OBS: Esta linha geralmente vem comentada dentro do arquivo global.asax devemos descomenta-la e fazer as alteraes necessrias
Imagem 5.

Pronto acabamos nosso projeto! Voc pode estar se perguntando, nossa mais no fiz quase nada... Para ver o resultado basta rodar sua aplicao, e voc ver as paginas de lista, insero, deleo e edio prontas para utilizao. Como nas imagens abaixo. Aqui temos o menu principal com acesso a todas as paginas do sistema: Veja a imagem 6.

Ao Clicar no link de Produtos olha que legal, teremos um grid com os produtos cadastrados, onde as colunas do Grid so as mesmas colunas da Tabela, e o mais interessante e o filtro que foi gerado automaticamente de acordo com as Chaves da tabela de Produtos, tem tambm a paginao do Grid e tudo isso sem escrever nenhuma linha de cdigo, temos tambm links para edio e deleo do produto e isso acontece para todas as tabelas relacionadas no diagrama. Note fizemos esse projeto em 45 min. Veja a imagem 7.

26

maro 2009

Imagem 6..

Imagem 7.

Voc pode estar se perguntando e o layout como fica, no gostei desse, esta fora do padro da minha empresa ou do meu site, no tem problema ele e feito todo em cima de CSS, voc poder customizar tudo, pode tambm gerar paginas personalizadas editar somente o GRID de Produtos, a ferramenta e bem Flexvel. Agora voc precisa tomar cuidado para que sua customizao no te leve a fazer tudo do zero ai vale mais apena fazer de outra maneira. Esta ferramenta trar maior benefcio se tiver pouca customizao. Espero ter ajudado.

Bons Cdigos...

Sobre o autor
Fabiano Belmonte
Senior Architect da InfoMoney.com, especialista em aplicaes e-Business com larga experincia em B2B (Submarino.Com e Saraiva.Com). Trabalha h 5 anos com a tecnologia .Net, aplicando conhecimentos nas diversas reas: instituies financeiras (sistema SPB), e-Commerce, gerenciamento logstico entre outras. Trabalhando com Visual Studio desde suas primeiras verses, responsvel pela implementao de uma Metodologia de trabalho e melhoras significativas no resultados e na qualidade do time de Desenvolvimento de muitas empresas por onde passou como (Saraiva.Com) e ferramentas como TFS (Team Foundation Server). Foi palestrante em eventos como Codificando. NET 2008 e outros eventos sobre Tecnologia .NET.
maro 2009

27

Dicas DELPHI
Ativar Auto Run do CD ROM
// Declare USES. Registry na seo Mascara := #$%$#13#12; Str2 := ; PonM := 1; for PonS:=1 to length(Str1) do begin AppendStr( Str2, Chr( Ord(Str1[PonS]) Xor Ord(Mascara[PonM]))); Inc( PonM); if PonM>Length(Mascara) then PonM:=1; end; Result := Str2; end;

procedure SetCDAutoRun(AAutoRun:Boolean); const DoAutoRun : array[Boolean] of Integer = (0,1); var Reg:TRegistry; begin try Reg := TRegistry.Create; Reg.RootKey := HKEY_LOCAL_ MACHINE; if Reg.KeyExists(System\ CurrentControlSet\Services\Class\ CDROM) then begin if Reg.OpenKey(System\ CurrentControlSet\Services\Class\ CDROM, FALSE) then begin Reg. WriteBinaryDataAutoRun, DoAutoRun[AAutoRun], 1); end; end; finally Reg.Free; end; ShowMessage(Esta alterao s ser ativada aps a reinicializao do PC.); end;

Ver se existe Midia no Drive

Criptografar Strings

function DiskInDrive(Drive: Char): Boolean; var ErrorMode: word; begin Drive: = UpCase(Drive); if not (Drive in [A..Z]) then raise EConvertError.Create(Not a valid drive ID); ErrorMode := SetErrorMode(SEM_ FailCriticalErrors); try if DiskSize(Ord(Drive) - $40) = -1 then DiskInDrive := False else DiskInDrive := True; finally SetErrorMode(ErrorMode); end; end;

function Criptografar( const Str1: string): String; var Mascara,Str2: String; PonM, PonS: Byte; begin

Ver Impressora Conectada

Function ImpresConect(Porta:Word):B oolean;

28

maro 2009

Const Portas :Byte = $02; Var Res :Byte; Begin Asm mov ah,Portas; mov dx,Porta; Int $17; mov Res,ah; end; Result := (Res and $80) = $80; end;

TForm1 = class(TForm) Label1: TLabel; ListBox1: TListBox; Button1: TButton; procedure ListBox1Click(Sender: TObject); procedure Button1Click(Sender: TObject); private { Private declarations } public { Public declarations } end; var Form1: TForm1; implementation

Localizar Arquivos no Windows

procedure TForm1. Button1Click(Sender: TObject); begin with TDDEClientConv.Create(Self) do begin ConnectMode := ddeManual; ServiceApplication := explorer. exe; SetLink( Folders, AppProperties); OpenLink; ExecuteMacro([FindFolder(, C:\ Windows)], False); CloseLink; Free; end; end

{$R *.DFM} // Evento OnClick do componente ListBox procedure TForm1.ListBox1Click(Sender: TObject); begin // A linha abaixo atribui a propriedade Caption do // componente Label o nome da fonte selecionada no // componente ListBox Label1.Caption := ListBox1. Items[ListBox1.ItemIndex]; // A linha abaixo muda a fonte de letra de acordo // com a fonte selecionada no componente Listbox Label1.Font.Name := ListBox1.Items[ListBox1.ItemIndex]; end; // Evento OnClick do componente Button procedure TForm1.Button1Click(Sender: TObject); begin // Carrega as fontes instaladas no Windows para // o componente ListBox ListBox1.Items := Screen.Fonts; end;

Mostrar as fontes True Types instaladas no Windows

unit Unit1; interface uses Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs, StdCtrls; type

maro 2009

29

30

maro 2009

maro 2009

maro 2009