Boas práticas de armazenamento de comandos Dapper .NET
Ao utilizar o Dapper em uma aplicação .NET, é importante organizar os comandos SQL de forma que eles sejam reutilizáveis, fáceis de manter e seguros.
-
Armazenar SQL em Arquivos Separados:
Armazene os comandos SQL em arquivos .sql dentro de uma pasta, como SQL/Queries. Use File.ReadAllText() para carregar os comandos.
Estrutura de pastas:/SQL /Product GetAllProducts.sql GetProductById.sql InsertProduct.sql UpdateProduct.sql DeleteProduct.sql
Exemplo de leitura:
```C# string sql = File.ReadAllText("SQL/Product/GetAllProducts.sql").Replace("\n", " ").Replace("\r", "").Trim();//(removendo espaços de identação) ```
Vantagens:
• Comandos SQL ficam separados do código C#, facilitando a leitura e a organização.
• Ideal para comandos SQL longos e complexos. -
Usar Recursos como Embedded Resources:
Armazene os comandos SQL em arquivos .sql e inclua-os como Recursos Incorporados no projeto. Carregue os arquivos com Assembly.GetManifestResourceStream.Exemplo de uso
• Configure o arquivo .sql como Embedded Resource nas propriedades do arquivo.
• Carregue o arquivo no código:```C# string sql; var assembly = Assembly.GetExecutingAssembly(); using (var stream = assembly.GetManifestResourceStream("YourNamespace.SQL.Product.GetAllProducts.sql")) using (var reader = new StreamReader(stream)) { sql = reader.ReadToEnd().Replace("\n", " ").Replace("\r", "").Trim();//(removendo espaços de identação) } ``` Vantagens: • SQL fica dentro do binário, evitando alterações acidentais no ambiente de produção. • Segurança adicional para proteger o código SQL.
Independente da forma de armazenamento, sempre use parâmetros nas consultas para evitar injeção de SQL.
Exemplo de uso seguro:
```C#
string sql = "SELECT * FROM Products WHERE Name = @Name";
var products = await connection.QueryAsync<Product>(sql, new { Name = "Example" });
```
Comparação em performance
-
Arquivos Externos:
As queries são armazenadas em arquivos .sql no sistema de arquivos e carregadas em tempo de execução.Vantagens de Performance
• Tamanho do executável menor: O binário final não inclui as queries diretamente.
• Separação de responsabilidades: Facilita a manutenção e atualização das queries sem recompilar o código.Desvantagens de performance
• Leitura de arquivos: Cada vez que um arquivo é acessado, há uma operação de I/O, que é mais lenta do que acessar strings em memória.
• Mitigação: Use cache em memória para armazenar queries lidas previamente.
• Risco de falhas: Se o arquivo for movido ou excluído, a aplicação pode falhar.Cenário de Uso
• Adequado para projetos grandes com queries longas ou complexas que precisam ser atualizadas com frequência sem alterar o código. -
Recursos Incorporados
As queries são armazenadas em arquivos .sql e configuradas como Embedded Resources no projeto, sendo incorporadas ao binário no momento da compilação.Vantagens de Performance
• Sem I/O no disco: Os recursos incorporados são acessados diretamente da memória do binário, eliminando operações de disco.
• Tamanho fixo do executável: As queries são incorporadas ao executável, evitando dependências externas.
• Organização: Manter queries separadas em arquivos melhora a legibilidade e manutenção.Desvantagens de Performance
• Maior consumo de memória inicial: Os recursos incorporados aumentam o tamanho do binário e são carregados na memória junto com a aplicação.
• Menor flexibilidade: Atualizar as queries exige recompilar o projeto.
Cenário de Uso
Ótimo para projetos onde as queries raramente mudam e há necessidade de um executável autossuficiente.
Comparação de Performance
Critério | Arquivo Externo | Recurso Incorporado |
---|---|---|
Velocidade de Acesso | Média (I/O de disco) | Alta (em memória) |
Tamanho do Binário | Menor | Maior |
Flexibilidade | Alta | Média |
Facilidade de Atualização | Alta | Baixa |
Conclusão
- Melhor para Manutenção e Flexibilidade:
• Arquivos Externos (permitem alterações sem recompilar a aplicação). - Recomendação Geral:
• Para projetos grandes e dinâmicos, use Arquivos Externos com cache em memória para balancear flexibilidade e desempenho.
Observações gerais
Alguns projetos são usados a string command diretamente como string estática no código fonte não caracterizando uma boa prática por conta de alguns fatores que podemos listar:
• Se o texto da query será carregado na memória com identação, serão armazenados e enviados como parte da consulta deixando o tamanho do binário maior.
• Implica na dificuldade de versionamento especificadamente do comando.
• Comando diretamente exposto no código pode não ter uma boa legibilidade, pois não separa a responsabilidade corretamente.
• Pode ser um ponto de atenção na questão de segurança, isso deve ser avaliado cada código em particular para identificar possíveis "furos".