Evite problema com Enums em WebServices ou WCF

Os famosos enums são muito bem vindos dentro da própria aplicação , mas no caso de webservices ou wcf temos um problema que ao gerar o proxy temos os valores validos para o enum, então mudar o serviço requer atualizar o proxy do cliente que consome.

Se o parametro é de entrada o problema é menor , mas se for um retorno não atualizar o proxy irá causar exception para novos valores.

Referência: http://www.25hoursaday.com/weblog/2005/08/31/WhyYouShouldAvoidUsingEnumeratedTypesInXMLWebServices.aspx

Transformar XML em Classe .Net

Esses dias estava querendo pegar um resultado de um webservice externo e trasnformar o xml no formato do meu objeto externo, essa parte fiz usando xslt sem problema. Feito isso eu queria gerar minha classe a partir do meu xml destino sem precisar fazer na mão =).

Uma rapida pesquisa encontrei no link abaixo a solução

http://stackoverflow.com/questions/4999928/i-want-to-convert-this-xml-to-c-sharp-code

A resposta que utilizei foi usar o xsd.exe para primeiro gerar o xsd do xml e depois usar xsd.exe para do xsd gerar minha classe =) … economizei umas 3 horinhas pelo menos =)

Usando Extensions e matando IF =)

Algum tempo atraz precisei desenvolver uma função para retornar o signo de uma pessoa com base na data de nascimento.

Poderia criar um classe com um metodo que passaria uma data e receberia uma string com o Signo , mas confesso que sou muito preguiçoso =)

Então resolvi criar um Extension metodo para extender DateTime, além disso resolvi bolar uma solução que não utilizasse Ifs “só sobrou um =)” :

Para eliminar if resolvi criar um list e depois utilizar linq para pesquisar na coleção.

public static class DateObjectExtensions
    {

        class SignoMesDia
        {
            public Int16 Mes { get; set; }
            public Int16 DiaInicio { get; set; }
            public Int16 DiaFim { get; set; }
            public string Signo { get; set; }

            public SignoMesDia(Int16 _Mes, Int16 _DiaInicio, Int16 _DiaFim, string _Signo)
            {
                Mes = _Mes;
                DiaInicio = _DiaInicio;
                DiaFim = _DiaFim;
                Signo = _Signo;

            }


        }

       

        public static string ToSigno(this DateTime DataNascimento)
        {
            string signo = "Não Reconhecido";

            List<SignoMesDia> signos = new List<SignoMesDia>();

            signos.Add(new SignoMesDia(1, 1, 21, "Capricórnio"));
            signos.Add(new SignoMesDia(1, 22, 31, "Aquário"));
            signos.Add(new SignoMesDia(2, 1, 18, "Aquário"));
            signos.Add(new SignoMesDia(2, 19, 31, "Peixes"));
            signos.Add(new SignoMesDia(3, 1, 19, "Peixes"));
            signos.Add(new SignoMesDia(3, 20, 31, "Áries"));
            signos.Add(new SignoMesDia(4, 1, 20, "Áries"));
            signos.Add(new SignoMesDia(4, 21, 31, "Touro"));
            signos.Add(new SignoMesDia(5, 1, 20, "Touro"));
            signos.Add(new SignoMesDia(5, 21, 31, "Gêmeos"));
            signos.Add(new SignoMesDia(6, 1, 20, "Gêmeos"));
            signos.Add(new SignoMesDia(6, 21, 31, "Câncer"));
            signos.Add(new SignoMesDia(7, 1, 21, "Câncer"));
            signos.Add(new SignoMesDia(7, 22, 31, "Leão"));
            signos.Add(new SignoMesDia(8, 1, 22, "Leão"));
            signos.Add(new SignoMesDia(8, 23, 31, "Virgem"));
            signos.Add(new SignoMesDia(9, 1, 22, "Virgem"));
            signos.Add(new SignoMesDia(9, 23, 31, "Libra"));
            signos.Add(new SignoMesDia(10, 1, 22, "Libra"));
            signos.Add(new SignoMesDia(10, 23, 31, "Escorpião"));
            signos.Add(new SignoMesDia(11, 1, 21, "Escorpião"));
            signos.Add(new SignoMesDia(11, 22, 31, "Sagitário"));
            signos.Add(new SignoMesDia(12, 1, 21, "Sagitário"));
            signos.Add(new SignoMesDia(12, 22, 31, "Capricórnio"));




            var resposta = (from s in signos where s.Mes == DataNascimento.Month && DataNascimento.Day >= s.DiaInicio && DataNascimento.Day <= s.DiaFim select s).FirstOrDefault();

            if (resposta != null)
                signo = resposta.Signo;



            return signo;

        }}

 

 

 

Validação Genérica com Reflection X Exception

Estava dando manutenção em um código que basicamente validava 30 campos com a seguinte regra.

Se o campo for vazio passar nulo para a procedure
Senão for validar se o campo é do tipo esperado (DateTime, Numeric, etc).

Basicamente o código era igual ao abaixo para cada campo.

string valor = “20/01/01”;
DateTime? data = null;
DateTime dataTemp;

if( (!string.IsNullOrEmpty(valor)) && DateTime.TryParse(valor, out dataTemp))
{
data = new Nullable<DateTime>(dataTemp);
}

Então resolvi cria uma função genérica e fazer testes de performance, para verificar qual solução implementar na solução. Veja as opções , ambas bem extensas =)

static bool TryParseException<T>(string text, out T value)
{

value = default(T);

try
{

value = (T)Convert.ChangeType(text, typeof(T));

return true;

}

catch
{

return false;

}

}

public static bool TryParseReflection<T>(string input, out T value) where T : struct
{
var type = typeof(T);
value = default(T);
var method = type.GetMethod(
“TryParse”,
new[] { typeof(string), Type.GetType(string.Format(“{0}&”, type.FullName)) });

return (bool)method.Invoke(null, new object[] { input, value });
}

Para os campos com valores compativeis com o tipo esperado a versão com Exception foi mais rápida, claro que era esperado porque com o valor esta no formato esperado não é disparada nenhum exception. Comparativo para 30 campos (0,015 s X 0.062 s)

Agora quandos os valores não são compativeis a versão que usa Reflection é infinitamente mais rápida. Comparativo para 30 campos (0,003 s X 1.5 s)

Pelos meus testes é bem mais interessante utilizar a versão com Reflection, pois mesmo quando é mais lenta é uma diferença que um usuário não perceberá a diferença.

Claro que se você for processar milhões de registros e 99.99% for o tipo correto seja mais interessante utilizar a versão com Exception =)

 

 

 

Estatistica SQL Server – Quando ocorreu a última atualização de estatisticas?

Estatisticas é a area de Banco de Dados mais deixada de lado, embora seja uma das  que mais afetam a performance de um Banco de dados. Não adianta ter um servidor parrudo, todos os indices criados , consultas bem escritas , se as estatisticas estiverem desatualizadas.

Isso acontece porque as estatisticas é o que indicara qual é o melhor caminho para uma consulta, qual indice utilizar, se será usado realizado um seek em determinado indice, scan ou um table scan .

Por exemplo se uma tabela tem 30 milhões de registros mas as estatisticas dizem que tem 300 mil. Uma consulta que  traga 50 mil registros será tratada totalmente diferentes nos dois casos, pois o SQL Server tem uma regra que se o resultado da consulta trouxer mais de 30% do total da tabela será realizado um table Scan , do contrário será analisado a possiblidade de utilizar algum indice. Por isso com as estatisticas  desatualizadas seria realizado um table Scan , já com a estatistica atualizada seria utilizado provavelmente um index seek.

Sempre quando tiver problema de performance verifique as estatisticas, e é claro tenha um plano de manutenção semanal para atualiza-las manualmente não confie na atualização automatica do SQL.

Checando Estatisticas

SELECT OBJECT_name(OBJECT_ID) Tabela, name AS Indice, STATS_DATE(OBJECT_ID, index_id) AS DataAtualizado
FROM sys.indexes where is_hypothetical  = 0
AND OBJECT_name(OBJECT_ID) NOT LIKE ‘sys%’ ORDER BY  OBJECT_name(OBJECT_ID)

Atualizando Estatistica

 UPDATE STATISTICS NomeTabela WITH  fullScan

Links Sobre Estatisticas
http://technet.microsoft.com/en-us/library/cc966419.aspxhttp://www.sqlskills.com/BLOGS/KIMBERLY/category/Statistics.aspx
http://blog.sqlauthority.com/2010/04/23/sql-server-update-statistics-are-sampled-by-default-2/
http://www.sqldev.org/transactsql/obtaining-statistics-metadata-58567.shtml

JQuery Remover Coluna Tabela

Para remover uma coluna da tabela com Jquery é só utilizar
Caso o cabeçalho da tabela não seja com th é só retirar o “, th:nth-child(1)”

$(‘#idTabela td:nth-child(1), th:nth-child(1)’).hide();

Importante lembrar que embora tenha sido removido o indice para acesso as demais colunas não muda , para alterar a largura da coluna 3 eu continuo usando
‘Repare que nesse caso o indice começa em zero e não 1
$(‘#idTabela tr:first th’).eq(2).css(‘width’, ’50px’);