Um conhecimento só é válido quando compartilhado.

sábado, 9 de abril de 2011

TFields vs FieldByName

Olá caro leitor, começo te fazendo uma pergunta, você usa TFields em tempo de design ? Quando comecei a trabalhar com Delphi, comecei a usar TFields em tempo de design, no decorrer do tempo vi que os TFields em tempo de design, me dava muito trabalho para dar manutenção a eles, as vezes ter que mudar de tipo, tamanho, mascara, valor default, pois o mesmo TFields as vezes precisava ser adicionado no dataset, em vários pontos do sistema. Na época achei um forma de minimizar, colocando os datasets em um único datamodule e o herdando, foi uma solução que minimizou a dor minha de cabeça com manutenção. Uns anos depois, quis desenvolver uma aplicação multicamadas e multibanco, mas os TFields estavam la para me dar dor de cabeça novamente, porque ao adicionar os TFields no Delphi, alguns tipos são diferentes dependendo do banco de dados. Bom a solução foi adicionar os TFields via código (runtime), assim independente do banco de dados os TFields iriam ser adicionados no seu tipo certo, dependendo do banco que eu estava usando, dei até uma palestra sobre esse assunto em 2006 na Borcon (Borland Conferência), isso resolveu meu problema, alem de centralizar todos os parâmetros de cada TField, podendo ser aproveitado que qualquer parte de meu sistema, mas esse recurso esplêndido que consegui, tem para meu sistema um custo um pouco alto, não tão alto que não compense, mas tem, pois tive que usar em todo meu sistema "FieldByName('')", e isso, para quem já debugou o código do Delphi, sabe que ao chamar um FieldByName, o delphi faz um loop (for) para achar o campo pelo seu nome então imaginemos:
while not DS.eof do
begin
  DS.FieldByName('Campo1').AsInteger := DS.FieldByName('Campo1').AsInteger * 
                                        DS.FieldByName('Campo2').AsInteger;
end;
No código acima vemos, um exemplo até simples, do qual o Delphi terá que fazer três vezes o mesmo loop (for), agora imaginemos se essa tabela usada tiver uns 80,90 até 100 ou mais campos, multipliquem isso por três. Fazendo o que gosto de fazer, que é navegar pela NET, procurando exemplos, código, recursos etc.. sobre Delphi, descobri um post em um blog, o qual falava justamente sobre TFields vs FieldByName, não estou lembrado aqui nesse momento qual o link, mas no blog dizia que para resolver essa questão de poderíamos criar uma variável do tipo TField, para cada FieldByName assim:
var
Campo1: TField;
Campo2: TField;
begin
  Campo1 := DS.FieldByName('Campo1');
  Campo2 := DS.FieldByName('Campo2');
  while not DS.eof do
  begin
    Campo1.AsInteger := Campo1.AsInteger * Campo2.AsInteger;
  end;
end;

Dessa forma o loop (for) só será executada uma vez e não três, bom até ai MUITO bom já baixaria o custo a quase zero, mas ao ver código pensei, não da para ficar criando variáveis a cada ponto que precisar usar desse recurso, da veio a idéia de ter uma class como a mesma estrutura de cada tabela e cada propriedade ser do tipo TField assim:
type
  TDS = class
  private
    FCampo1: TField;
    FCampo2: TField;
  public
    property Campo1: TField read fCampo1 write Campo1;
    property Campo2: TField read fCampo2 write Campo2;
end;
...
Em seguida criar o link de forma automatizada, para eu não ter que ficar dando manutenção toda vez que adicionar um campo ou remover caso for preciso, é isso que irei mostrar para vez como fazer no meu próximo post. Abraço a todos e até la.

Baixe um demo no link meu link na Embarcadero http://cc.embarcadero.com/Author/55953

10 comentários :

  1. Olá Isaque !

    Vi seu exemplo no site da Embarcadero. Gostaria de fazer uma pergunta. Você utiliza o AP_Server.TBL apenas para expor os metodos do seridor? Ou seja, posso expor meu servidor usando DataSnap e o conceito que você nos apresentou? Ou preciso de qualquer forma usar o AP_Server.TBL?

    Grande abraço e parabéns pelo exemplo.

    André Medeiros
    andremedeiros@asolutions.com.br

    ResponderExcluir
  2. fica aqui outra pergunta e se usarmos direto tipo assim
    datamodule.fdqueryNOME.asstring := 'JOSE';
    assim não precisa usar o fieldbyname né?

    ResponderExcluir
    Respostas
    1. Exato Sarvério, mas dessa forma foi criado uma VAR do tipo TField na memória para que você o substitua pelo FieldByName().
      Porem essa VAR é o TField que é criado em Designer direto no DataSet.
      O Que isso traz manutenção? É que como essa VAR (TField) fica no Dataset, e vc configura as propriedades MasEdit, DisplayFormat etc.. e se no seu sistema tiver dois ou mais lugares que vc use um Dataset para mostrar dados em telas diferentes, terá que configurar cada VAR (TField) em cada Dataset, de cada tela, por isso TField em designer não é uma boa opção, mas sim em runtime.

      Excluir
    2. O ORMBr por exemplo, usa a técnica de criar os TFields em runtime, e no momento de criação, ele usa os atributos do modelo para parametrizar varias propriedades como DefaultExpression, EditMas, DisplayFormat etc...

      Excluir
    3. Nesse link acima tem um exemplo "Applications without TFields", que mostra criar os TFields em runtime.

      A Situação de criar TField em runtime, é que como vc não cri a VAR (Tfield) no Dataset pela IDE do delphi, teria que usar sempre FieldByName(), e isso quer queira ou não gera um processo a mais para o EXE achar o campo pelo nome.

      Ai vem a técnica de criar a classe como mostrado no artigo, que vc irá substituir as VAR (Tfields) pelas propriedades da classe.

      Excluir
  3. Isaque e se usarmos assim
    DataSource.Dataset.FieldValues['Nome'] := 'JOAO';
    DataSource.Dataset.FieldValues['Codigo'] := 23 ;

    não seria necessario criar variaveis em design Time e seria uma maneira mais adequada de trabalhar?

    ResponderExcluir
    Respostas
    1. Savério tudo que vc use 'name' ou seja em String faz loop interno.
      Agora se vc usa versões mais novas do Delphi ele estão usando tdictionary interno, já vale a pena para não usar tfield em designer.

      Excluir

SAC Automação Delphi e Lazarus

SAC Automação Delphi e Lazarus
Assine nosso SAC Automação Delphi e Lazarus para ter suporte técnico especializado em desenvolvimento

Quem sou eu

Minha foto

Proprietário/Administrador de Empresa em TI (Tecsis Informática)
  • Autor dos projetos OpenSource ORMBr, e DBCBr
  • Autor dos componentes ACBrInstall, ACBrSped, ACBrPaf, ACBrInStore, ACBrDownload.

Total de visualizações

Postagem em destaque

ORMBr - Mapeamento objeto-relacional

Mapeamento objeto-relacional ( ou ORM, do inglês: Object-relational mapping ) é uma técnica de desenvolvimento utilizada para reduzir...

Todo os direitos reservados.. Tecnologia do Blogger.

Seguidores

Google+ Seguindores