quinta-feira, 14 de março de 2013

Query com Reflection

Hoje tive que criar queries na mão, pois preciso fazer uma importação e o NHibernate demoraria muito para salvar os objetos.

Estava com preguiça de criar as queries uma a uma, olhando as propriedades do objeto. Então lembrei de reflection. Por que não? Afinal de contas, virei programadora porque detesto trabalho repetitivo...

Fiz uma iteração pelos tipos que queria e gravei de um arquivo.

using System;
using System.Collections.Generic;
using System.IO;


            var tipos = new[]
            {
                typeof ([tipo 1]),
                typeof ([tipo 2]),
            };

            var query = new List<String>();

            foreach (var tipo in tipos)
            {
                var colunas = new List<String>();
                var valores = new List<String>();

                var nomeTipo = tipo.Name.ToLower();

                foreach (var propertyInfo in tipo.GetProperties())
                {
                    if (propertyInfo.Name == "ID")
                        continue;
                 
                    colunas.Add(propertyInfo.Name);
                    valores.Add("\" + " + nomeTipo + "." + propertyInfo.Name + ".ToSql() + \"");
                }

                query.Add("@\"Insert into " + nomeTipo + " (" + String.Join(", ", colunas) + ")");
                query.Add(" Values (" + String.Join(", ", valores) + ")\";");


                var atribuicao = new List<String>();

                query.Add("@\"Update " + nomeTipo + " set ");

                foreach (var propertyInfo in tipo.GetProperties())
                {
                    if (propertyInfo.Name == "ID")
                        continue;

                    atribuicao.Add(propertyInfo.Name + " = \" + " + nomeTipo + "."
                        + propertyInfo.Name + ".ToSql() + \"");
                }

                query.Add(String.Join(", ", atribuicao) + " where ID = \" + "
                    + nomeTipo + ".ID + \"\";");

            }

            File.WriteAllLines([caminho do arquivo], query);


Então você pega o resultado do arquivo e cola no seu código. Melhor que ficar copiando as propriedades uma por uma.

2 comentários:

  1. É uma ótima idéia mesmo. Como temos várias queries nativas que precisamos rodar no trabalho - tem bastante lógica no banco (don't ask :-/) - usamos uma abordagem parecida. Só tome cuidado porque, em Java por exemplo, eles náo recomendam usar pra tudo por questões de performance, se não me engano.

    ResponderExcluir
    Respostas
    1. Na verdade, a ideia aqui é você usar como gerador, gerar o que precisa e deixar fora da aplicação. Reflection é linda, mas é programação de programação. F... com a performance. No máximo, e imagino que ORMs usem mais ou menos isso, você poderia gerar as queries no start da aplicação e deixar em algum lugar estático pra ser usado durante.

      Excluir