QUERY PARAMETRIZADA

PERCIFILHO 18/04/2016 13:14:50
#461079
Boa tarde, pessoal.
Estou tentando melhorar meus códigos para tornar o mais fácil possível de manutenção e leitura. E estava querendo saber como faço na seguinte questão:
Hoje eu tenho um comando dentro de uma função para preencher uma List<T> com todos os registros da tabela. Assim:

 
public List<T> Todos()
cmd.CommandText = [Ô]Select * From {0}[Ô];
cmd.CommandText = string.Format(cmd.CommandText, typeof(T).Name);


Agora eu queria melhorar isso, com opções de poder especificar quando tiver uma condição, inclusive a ordenação.
Teria que ficar assim:

cmd.CommandText = [Ô]Select * From {0} Where {1} Order By {2} {3}[Ô];


onde tanto Where {1} quanto Order By {2} teria que ser uma array, visto que eu poderia ter mais de uma condição e mais de uma ordem. O {3} seria Asc ou Desc.

Ficaria mais ou menos assim:
public List<T> Todos(array_da_condição, array_da_ordem, string Asc_Desc)
cmd.CommandText = [Ô]Select * From {0} Where {1} Order By {2} {3}[Ô];
cmd.CommandText = string.Format(cmd.CommandText, typeof(T).Name, array_da_condicao, array_da_ordem, Asc_Desc);


Não sei se consegui me expressar direito, espero que sim.
Se alguém que entendeu puder me ajudar, agradeço. Se não entenderam posso tentar explicar novamente.
Obrigado desde já.
KERPLUNK 18/04/2016 21:56:14
#461102
Resposta escolhida
Bom, existem várias maneiras de se implementar o que você quer:
1 - Implementar um QueryProvider. De longe a melhor, mas também de longe a mais complexa. Com ela implementada você pode usar LINQ ou expressões lambda para buscar dados, fazer ordenação e virtualmente qualquer operação SQL desejada. é exatamente isso que o Entity Framework utiliza. Você usaria comandos como:

List<Clientes> clientes = MeuBanco.Cliente.Where(c => c.Descricao.Contains([Ô]%claudio%[Ô]) & c.DataCadastro >= new DateTime(2010, 12, 13)).OrderBy(o => o.Descricao);

O comando acima, resultaria na query [Ô]Select * from Clientes where Descricao Like [ô]%claudio%[ô] And DataCadastro >= [ô]13/12/2010[ô] Order By Descricao[Ô].

2 - Implementar um método que receba uma lista de parâmetros tipados. Ficaria mais ou menos assim:

List<Parametro> pars = new List<Parametro>
pars.Add(new Parametro() { Tipo = TiposParametros.Condicao, Operador = Operadores.Like, Campo = [Ô]Descricao[Ô], Valor = [Ô]%claudio%[Ô] };
pars.Add(new Parametro() { Tipo = TiposParametros.Condicao, Operador = Operadores.MaiorIgual, Campo = [Ô]DataCadastro[Ô], Valor = new DateTime(2010,12,13) };
pars.Add(new Parametro() { Tipo = TiposParametros.Ordem, Campo = [Ô]Descricao[Ô] };

List<Cliente> clientes = new Cliente.Todos(pars);

O código acima resultaria na mesma query anterior. Um pouco mais trabalhoso para se usar, mas com o mesmo resultado e implementação bem mais simples, precisando apenas [Ô]percorrer[Ô] parâmetros e adicionar no comando SQL básico conforme o tipo de parâmetro.

3 - Uma solução muito parecida com a segunda, seria um método que recebe parâmetros livremente, sem especificar um número ou tipo exato. é quase o mesmo que a solução acima, mas dá a idéia de ser mais [Ô]livre[Ô]:

public static void Todos(params object[] args)
{
}

E então você simplesmente passaria parâmetros para o método, quantos quiser, dos tipos que quiser. Esse approach, foge um pouco do objetivo da OOP fortemente tipada, mas é uma alternativa viável.

Agora assim de cara é o que consigo pensar para te ajudar. Você pode avaliar os prós e contras dessas opções e usar uma delas que eu ajudo.
PERCIFILHO 19/04/2016 08:04:42
#461116
Vou pesquisar mais sobre esse tal de QueryProvider. Se tiver algum lugar para me indicar, eu agradeço, vou pesquisar no Google e ver o que eu acho. Esse link que você passou não abriu. Obrigado pelas explicações.
Tópico encerrado , respostas não são mais permitidas