Porque e como utilizar queries LINQ em um Pattern Repository
Então você decidiu adotar software patterns para melhoria no desenvolvimento de sistemas e acha que tudo estará resolvido!?
Montou uma framework própria baseada em bibliotecas existentes que obedece às N regras de separação de camada, desacopalhamentos e etc.
Então foi executar o sistema em produção e ele está uma lentidão que não consegue descobrir o motivo.
Considerando que o gargalo está ocorrendo nas consultas ao banco de dados, independente de qualquer framework de acesso a dados adotada, temos que tomar cuidado com o mapeamento dos campos de cada entidade e ainda, sabermos projetar as colunas que efetivamente iremos utilizar nas consultas, porque por padrão quando, por exemplo, vamos acessar a uma coleção para listar registros, todas as propriedades serão populadas pela projeção de todos os campos mapeados, exceção às propriedades 1-1, 1-n e n-n que trabalharão de acordo com a configuração de lazy load.
Como resultado uma consulta "simples" tipo:
Gerará a seguinte query (obedecendo ao mapeamento existente - desnecessário expor):
select ROTINACONT0_.CODIGO as CODIGO16_0_, ROTINACONT0_.CODIGOPLANOCONTAS as CODIGOPL2_16_0_,
PLANOCONTA1_.CODIGO as CODIGO128_1_, PLANOCONTA1_.CODIGOPLANOCONTAS as CODIGOPL2_128_1_,
ROTINACONT0_.DTREG as DTREG16_0_, ROTINACONT0_.USOREG as USOREG16_0_, ROTINACONT0_.HORAREG as HORAREG16_0_,
ROTINACONT0_.NOME as NOME16_0_, ROTINACONT0_.CODIGOTIPOCONTABIL as CODIGOTI7_16_0_,
ROTINACONT0_.CODIGOCONTADEBITOPAGAMENTO as CODIGOCO8_16_0_, PLANOCONTA1_.NOME as NOME128_1_,
PLANOCONTA1_.CODIGOCONTAMAE as CODIGOCO4_128_1_, PLANOCONTA1_.TIPO as TIPO128_1_,
PLANOCONTA1_.NATUREZA as NATUREZA128_1_, PLANOCONTA1_.CODIGOREDUZIDO as CODIGORE7_128_1_,
PLANOCONTA1_.CODRAUX as CODRAUX128_1_, PLANOCONTA1_.NIVEL as NIVEL128_1_,
PLANOCONTA1_.CONTROLE as CONTROLE128_1_, PLANOCONTA1_.MOSTRANOBALANCO as MOSTRAN11_128_1_,
PLANOCONTA1_.CODIGOPERMANENCIA as CODIGOP12_128_1_, PLANOCONTA1_.CODIGOAUXILIAR as CODIGOA13_128_1_,
PLANOCONTA1_.DTREG as DTREG128_1_, PLANOCONTA1_.HORAREG as HORAREG128_1_, PLANOCONTA1_.USOREG as USOREG128_1_,
PLANOCONTA1_.NAOINTEGRARCONTABILIDADE as NAOINTE17_128_1_, PLANOCONTA1_.NAOMOSTRARNODEREX as NAOMOST18_128_1_,
PLANOCONTA1_.CONTAFIXA as CONTAFIXA128_1_, PLANOCONTA1_.CODIGODEORDEM as CODIGOD20_128_1_,
PLANOCONTA1_.ATRIBUIRVALORDE as ATRIBUI21_128_1_, PLANOCONTA1_.NAOCONTABILIZARNOBANCO as NAOCONT22_128_1_,
PLANOCONTA1_.TIPODEMOVIMENTO as TIPODEM23_128_1_, PLANOCONTA1_.COLUNAFLUXO as COLUNAF24_128_1_,
PLANOCONTA1_.CONTAANTIGA as CONTAAN25_128_1_, PLANOCONTA1_.CONTAPARADIRF as CONTAPA26_128_1_,
PLANOCONTA1_.CODIGOCONTAREDUTORA as CODIGOC27_128_1_,
PLANOCONTA1_.LANCARCENTROCUSTOCONTABILIDADE as LANCARC28_128_1_,
PLANOCONTA1_.LANCARATIVIDADECONTABILIDADE as LANCARA29_128_1_,
PLANOCONTA1_.CADASTRAIMOBILIZADO as CADASTR30_128_1_, PLANOCONTA1_.DIRETAINDIRETA as DIRETAI31_128_1_,
PLANOCONTA1_.CODIGOHISTORICO as CODIGOH32_128_1_, PLANOCONTA1_.CONTAQDFINANCEIRAVEMDOPRODUTO as CONTAQD33_128_1_,
PLANOCONTA1_.TIPOLANCAMENTOORCAMENTO as TIPOLAN34_128_1_, PLANOCONTA1_.FORMACALCULOFOLHA as FORMACA35_128_1_,
PLANOCONTA1_.FORMULACALCULOORCAMENTO as FORMULA36_128_1_, PLANOCONTA1_.CODIGOCONTALALUR as CODIGOC37_128_1_,
PLANOCONTA1_.REGISTROIMPORTACAOPROCESSO as REGISTR38_128_1_, PLANOCONTA1_.VALORPADRAO as VALORPA39_128_1_,
PLANOCONTA1_.CODIGOCONTAGRUPOORCAMENTARIO as CODIGOC40_128_1_, PLANOCONTA1_.VARIACAOALERTA as VARIACA41_128_1_,
PLANOCONTA1_.NUMEROMESESCOMECACAIXA as NUMEROM42_128_1_, PLANOCONTA1_.NUMEROPARCELASGERAL as NUMEROP43_128_1_,
PLANOCONTA1_.CODIGOCENTROCUSTO as CODIGOC44_128_1_,
PLANOCONTA1_.CODIGOPLANOCONTASREFERENCIAL as CODIGOP45_128_1_,
PLANOCONTA1_.CENTROCUSTOOBRIGATORIO as CENTROC46_128_1_, PLANOCONTA1_.LIVROCAIXA as LIVROCAIXA128_1_,
PLANOCONTA1_.GRUPORELBALANCETE as GRUPORE48_128_1_, PLANOCONTA1_.DETALHACONTABILIDADEBANCO as DETALHA49_128_1_,
PLANOCONTA1_.NATUREZAFCONT as NATUREZ50_128_1_, PLANOCONTA1_.DEDUZIRDACONTRAPARTIDA as DEDUZIR51_128_1_,
PLANOCONTA1_.NAORATEARENCCONTASRENEG as NAORATE52_128_1_, PLANOCONTA1_.TIPO2 as TIPO53_128_1_,
PLANOCONTA1_.PROCESSOCAIXAESCOLAR as PROCESS54_128_1_, PLANOCONTA1_.TEMJUROS as TEMJUROS128_1_,
PLANOCONTA1_.TEMMULTA as TEMMULTA128_1_, PLANOCONTA1_.TEMRETENCAO as TEMRETE57_128_1_,
PLANOCONTA1_.TEMDESCONTO as TEMDESC58_128_1_, PLANOCONTA1_.NOMEAUXILIAR as NOMEAUX59_128_1_,
PLANOCONTA1_.APARECERRECEBIMENTO as APARECE60_128_1_, PLANOCONTA1_.APARECERPAGAMENTO as APARECE61_128_1_,
PLANOCONTA1_.CUSTEIO as CUSTEIO128_1_, PLANOCONTA1_.CAPITAL as CAPITAL128_1_,
PLANOCONTA1_.CUSTEIOCAPITAL as CUSTEIO64_128_1_, PLANOCONTA1_.TIPOAPLICACAO as TIPOAPL65_128_1_,
PLANOCONTA1_.RECEITAS as RECEITAS128_1_, PLANOCONTA1_.RESSARCIMENTOS as RESSARC67_128_1_,
PLANOCONTA1_.CODIGOSDOCUMENTOS as CODIGOS68_128_1_, PLANOCONTA1_.COLUNAVALOR as COLUNAV69_128_1_,
PLANOCONTA1_.CODIGOGRUPORESULTADO as CODIGOG70_128_1_, PLANOCONTA1_.CODIGOPRODUTO as CODIGOP71_128_1_,
PLANOCONTA1_.INDTIPOOPERACAOPISCOFINS as INDTIPO72_128_1_, PLANOCONTA1_.NATUREZABCPISCOFINS as NATUREZ73_128_1_,
PLANOCONTA1_.INDORIGEMCREDITOPISCOFINS as INDORIG74_128_1_
from TABROTINACONTABILCAIXA ROTINACONT0_
left outer join TABPLANOCONTAS PLANOCONTA1_ on ROTINACONT0_.CODIGOCONTADEBITOPAGAMENTO = PLANOCONTA1_.CODIGO and
ROTINACONT0_.CODIGOPLANOCONTAS = PLANOCONTA1_.CODIGOPLANOCONTAS
where ROTINACONT0_.CODIGOTIPOCONTABIL = @ P0 and
ROTINACONT0_.CODIGOPLANOCONTAS = @ P1
(sendo os parâmetros passados em ComTipoContabil() @P0 = tipoContabil e @P1 = planoContaContaContabil)
TODAS AS COLUNAS mapeadas são projetadas mesmo que façamos acesso à propriedade de apenas uma em código - no caso só preciso da propriedade Tipo em TABPPLANOCONTAS.
A maneira otimizada e que torna a consulta como se fosse a execução de um SQL puro (se fossemos fazer na mão sem usar o repositório) é a seguinte:
Vejam que podemos utilizar tudo como já ocorre na pattern repository sobre filtros - o ComTipoContabil() no caso, sem nenhum impedimento
.
select PLANOCONTA2_.TIPO as COL_0_0_
from TABROTINACONTABILCAIXA ROTINACONT0_
left outer join TABPLANOCONTAS PLANOCONTA2_ on ROTINACONT0_.CODIGOCONTADEBITOPAGAMENTO = PLANOCONTA2_.CODIGO and
ROTINACONT0_.CODIGOPLANOCONTAS = PLANOCONTA2_.CODIGOPLANOCONTAS
where ROTINACONT0_.CODIGOTIPOCONTABIL = @ P0 and
ROTINACONT0_.CODIGOCONTADEBITOPAGAMENTO = @ P1
Apenas os campos (e joins também, faça o seu teste para confirmar) que realmente são necessários são projetados, isso gera um ganho enorme de performance pelo custo menor de acesso ao banco de dados e do lado da aplicação menos custo para o bind de "valor de campo-propriedade da coleção" pois o retorno é uma lista de objetos anônimos apenas com as propriedades das colunas projetadas.
OBS: os aliases colocados pela ORM são automáticos.
Referências:
- https://pt.wikipedia.org/wiki/Mapeamento_objeto-relacional
- http://www.macoratti.net/11/10/net_pr1.htm
- http://martinfowler.com/eaaCatalog/repository.html
Comentários
Postar um comentário