<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>tucaz.blog.now() &#187; .NET</title>
	<atom:link href="http://blog.tucaz.net/category/desenvolvimento/net/feed/" rel="self" type="application/rss+xml" />
	<link>http://blog.tucaz.net</link>
	<description>Software architecture, agile and all that stuff that you can find everywhere</description>
	<lastBuildDate>Tue, 11 Jan 2011 21:00:29 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=2.9.1</generator>
	<language>br</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<item>
		<title>Come&#231;ando a aprender F# com: Ubuntu, Mono e Vim</title>
		<link>http://blog.tucaz.net/2011/01/10/comeando-a-aprender-f-com-ubuntu-mono-e-vim/</link>
		<comments>http://blog.tucaz.net/2011/01/10/comeando-a-aprender-f-com-ubuntu-mono-e-vim/#comments</comments>
		<pubDate>Tue, 11 Jan 2011 00:58:47 +0000</pubDate>
		<dc:creator>tucaz</dc:creator>
				<category><![CDATA[.NET]]></category>
		<category><![CDATA[Desenvolvimento]]></category>
		<category><![CDATA[FSharp]]></category>
		<category><![CDATA[Linux]]></category>
		<category><![CDATA[Vim]]></category>
		<category><![CDATA[F#]]></category>
		<category><![CDATA[fp]]></category>
		<category><![CDATA[functional programming]]></category>
		<category><![CDATA[mono]]></category>
		<category><![CDATA[ubuntu]]></category>
		<category><![CDATA[vi]]></category>

		<guid isPermaLink="false">http://blog.tucaz.net/?p=479</guid>
		<description><![CDATA[Já faz algum tempo que estou meio de saco cheio de desenvolvimento comercial tradicional que a maioria de nós, desenvolvedores, está acostumado a fazer. De uma forma ou de outra, exceto em projetos excepcionais tudo é uma variação de CRUD o que é um pé no saco pra quem gosta de código. Chega uma hora [...]]]></description>
			<content:encoded><![CDATA[<p>Já faz algum tempo que estou meio de saco cheio de desenvolvimento comercial tradicional que a maioria de nós, desenvolvedores, está acostumado a fazer. De uma forma ou de outra, exceto em projetos excepcionais tudo é uma variação de CRUD o que é um pé no saco pra quem gosta de código. Chega uma hora que a gente começa a procurar maneiras diferentes (não necessariamente melhores) de fazer a mesma coisa só pra acabar com o tédio. Isso estava me incomodando.</p>
<p>Há alguns meses quando este sentimento veio novamente decidi que iria tentar algo diferente. Foi ai que comecei com o combo título deste post. Uma mudança radical de ares.</p>
<p>Não sou o primeiro e com certeza não serei o último.</p>
<p>Apesar de trabalhar com Windows e depender dele pro meu ganha pão adotei o Ubuntu como sistema operacional padrão deixando o Windows em uma VM <strong>[1]</strong> apenas para trabalho e comecei a estudar F# que é uma linguagem com paradigma funcional que é completamente diferente de C#, Java e parentes próximos. Não bastasse a mudança de sistema operacional e de paradigma decidi também aprender mais a respeito de shell e editores de texto pra me livrar mais ainda dos atalhos que uma IDE como o VS proporcionam e adotei o VIM como editor de texto.</p>
<p>Nest post vou mostrar como montar um ambiente como o meu e os primeiros (primeiros mesmo, nada avançado) passos nessa estrada de aprendizado. Se tudo der certo e eu não desistir transformo numa série pra poder compartilhar meu aprendizado e com a colaboração de vocês aprender mais sobre o assunto.</p>
<p>Tudo que estou fazendo é no Ubuntu 10.10, mas deve funcionar com uma boa parte dos *nix por ai.</p>
<h3>Instalando F# com Mono</h3>
<p>Provavelmente o Linux que você tem instalado já deve ter o mono instalado, portanto não precisamos nos preocupar com esta etapa. De qualquer forma, só pra garantir abra o shell (Terminal) veja se você está realmente como o Mono instalado e qual sua versão:</p>
<pre class="shell" name="code">mono -V</pre>
<p>Se tudo estiver certo teremos algo parecido com isso:</p>
<pre class="bash" name="code">Mono JIT compiler version 2.6.7 (Debian 2.6.7-3ubuntu1)
Copyright (C) 2002-2010 Novell, Inc and Contributors. www.mono-project.com
    TLS:           __thread
    GC:            Included Boehm (with typed GC and Parallel Mark)
    SIGSEGV:       altstack
    Notifications: epoll
    Architecture:  amd64
    Disabled:      none</pre>
<p>Caso ele não esteja instalado basta ir ao Ubuntu Software Center <strong>[2] </strong>para instalá-lo ou <a title="Mono Downloads" href="http://www.go-mono.com/mono-downloads/download.html">baixá-lo no site oficial</a>.</p>
<p>Com Mono instalado corretamente e acessível de qualquer lugar precisamos agora baixar a última versão disponível da biblioteca e compilador FSharp. Temos três opções para a instalação: </p>
<ol>
<li>Efetuar o download do código fonte, compilá-lo e efetuar a instalação </li>
<li>Baixar um <a href="http://fsxplat.codeplex.com/">pacote cross-platform</a> que faz a instalação de tudo </li>
<li>Baixar o pacote oficial compilado, efetuar a instalação e configurar as variáveis de ambiente “manualmente” </li>
</ol>
<p>Vamos com a terceira opção, pra ver onde vai cada coisa e como cada um dos executáveis funciona.</p>
<p>A última versão disponível no momento deste post é a 2.0.0.0 de Novembro de 2010.</p>
<p>Como somos usuários ninjas de Linux vamos efetuar o download via linha de comando com <a href="http://www.gnu.org/software/wget/">wget</a>.</p>
<pre class="bash" name="code">wget http://download.microsoft.com/download/4/5/B/45BD9FBC-22BA-4B45-84B7-17D1AD0122A1/fsharp.zip</pre>
<p>Terminado o download, um pacote zip, extraimos todo o conteúdo pra uma pasta qualquer.</p>
<pre class="bash" name="code">unzip fsharp.zip</pre>
<p>Agora devemos ter todo o conteúdo do zip extraido em uma pasta chamada <em>FSharp-2.0.0.0</em>.</p>
<p>Antes de instalar sugiro mover a pasta com o conteúdo extraido do zip para um local mais apropriado para este tipo de arquivos já que é a partir desta pasta que iremos fazer referência mais pra frente aos executáveis do FSharp. Eu utilizo <em>/usr/lib/ </em><strong>[3]</strong>. Além de mover, vamos renomear a pasta de destino apenas para fsharp a fim de deixar tudo mais simples.</p>
<pre class="bash" name="code">sudo mv FSharp-2.0.0.0/ /usr/lib/fsharp/
cd /usr/lib/fsharp/</pre>
<p>Agora para instalar basta executar:</p>
<pre class="bash" name="code">cd fsharp
sudo sh install-mono.sh</pre>
<p>Este comando provavelmente retornará um erro indicando que a DLL não pôde ser adicionada ao GAC por conta de seu strongname. O que acontece é que a versão compilada que baixamos está com uma assinatura para o .NET Framework do Windows então antes de conseguir instalar o FSharp no Mono devemos baixar um <a title="mono.snk @ GitHub" href="https://github.com/mono/mono/raw/master/mcs/class/mono.snk">arquivo.snk</a> próprio para ele e ai sim executar novamente o setup.</p>
<pre class="bash" name="code">wget -O mono.snk https://github.com/mono/mono/raw/master/mcs/class/mono.snk --no-check-certificate
sudo sh install-mono.sh</pre>
<p>Dando tudo certo, devemos receber uma mensagem de sucesso:</p>
<pre class="bash" name="code">-- Resigning FSharp.Core.dll with mono.snk
Assembly bin/FSharp.Core.dll signed.
-- Installing FSharp DLLS into the GAC
Installed bin/FSharp.Core.dll into the gac (/usr/lib/mono/gac)</pre>
<p>Pra testar se tudo der certo, ainda de dentro do diretório onde instalamos o FSharp, podemos executar:</p>
<pre class="bash" name="code">mono bin\fsi.exe</pre>
<p>Se tudo estiver OK vamos entrar no FSharp Interactive que é uma console <a title="REPL @ Wikipedia" href="http://en.wikipedia.org/wiki/Read-eval-print_loop">REPL</a> pra F# muito legal:</p>
<pre class="bash" name="code">Microsoft (R) F# 2.0 Interactive build 2.0.0.0
Copyright (c) Microsoft Corporation. All Rights Reserved.

For help type #help;;

&gt; </pre>
<p>Podemos também fazer o tradicional “Hello World”:</p>
<pre class="bash" name="code">&gt; printfn &quot;Hello World!&quot;;;
Hello World!
val it : unit = ()</pre>
<p><strong>Pronto! </strong></p>
<p>Tecnicamente temos o FSharp instalado com sucesso e pronto para usar. No entanto, tanto o compilador (fsc.exe) e o REPL (fsi.exe) não fazem parte do PATH configurado em nosso Linux. Desta forma, ele está apenas acessível a partir do diretório onde está localizado.</p>
<p>Pra resolver isso vamos baixar o pacote de ferramentas adicionais para FSharp que irá nos prover algums aliases que permitirão o acesso as ferramentas a partir de qualquer diretório.</p>
<p>Dessa vez, como este pacote está hospedado no Codeplex, temos que efetuar o download do pacote “Additional scripts and tools only (.tgz archive)” manualmente localizado em <a title="http://fsxplat.codeplex.com/releases/view/55463" href="http://fsxplat.codeplex.com/releases/view/55463">http://fsxplat.codeplex.com/releases/view/55463</a>. </p>
<p></p>
<p>Feito o download podemos voltar ao nosso querido shell e instalar o pacote de bonus.</p>
<pre class="bash" name="code">cd ~/Downloads
mkdir fsharp-bonus
tar -xvzf fsharp-bonus.tgz -C fsharp-bonus
cd fsharp-bonus
sudo bash install-bonus.sh</pre>
<p>Este script de instalação espera que as DLLs do FSharp estejam na pasta <em>/usr/lib/fsharp. </em>No entanto, no nosso caso elas se encontram em <em>/usr/lib/fsharp/bin</em>, portanto caso o script solicite esta informação, fica fácil de prover. <img src='http://blog.tucaz.net/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </p>
<p>Feito isso é hora de testar e já podemos chamar <em>fsharpi</em> de qualquer lugar no shell:</p>
<pre class="bash" name="code">tucaz@tucaz-nb:~$ fsharpi

Microsoft (R) F# 2.0 Interactive build 2.0.0.0
Copyright (c) Microsoft Corporation. All Rights Reserved.

For help type #help;;

&gt; </pre>
<p>Agora podemos chamar tanto o REPL quanto o compilador a partir de qualquer diretório já que os alias foram devidamente criados e adicionados ao PATH.</p>
<h3>Primeiro Hello World com Vim</h3>
<p>Agora que temos todo o ambiente instalado (o que na minha opinião é um dos primeiros grandes obstáculos no aprendizado de uma nova linguagem) podemos fazer nosso primeiro Hello World e gerar uma DLL .NET com F#!</p>
<p>Primeiro, vamos definir um diretório de trabalho onde vamos colocar todos nossos projetos. Eu costumo usar um diretório chamado <em>Workspace</em> dentro do meu profile:</p>
<pre class="bash" name="code">cd ~
mkdir Workspace
cd Workspace
mkdir HelloWorldFSharp
cd HelloWorldFSharp</pre>
<p>Criado o diretório, criamos também nosso primeiro arquivo com código fonte FSharp utilizando o Vim <strong>[4]</strong>:</p>
<pre class="bash" name="code">vim HelloWorldFSharp.fs</pre>
<p>Isso cria um arquivo chamado HelloWorldFSharp.fs (assumindo que um não exista ou abre para edição caso ele exista) e o abre no nosso editor de texto funcionando dentro de um terminal shell, que pra um usuário Windows (que não tenha usado o Edit do DOS) é algo geralmente desconhecido.</p>
<p>O Vim (como o Vi) oferece basicamente dois modos de trabalho: modo de comando e edição/inserção de texto. Quando abrimos um arquivo, por padrão temos o modo de comando onde o texto digitado não é o que vai para o arquivo, mas sim interpretado como um comando (a seguir).</p>
<p>Para entrar no modo de edição de texto digitamos <em>i</em> ou apertamos a tecla <em>insert</em> do teclado. Note que o texto &#8211;INSERT&#8211; irá aparecer no canto esquerdo inferior da tela indicando que agora estamos no modo de inserção de texto. Esta área é destinada aos comandos e mensagens do editor.</p>
<p>Estando no modo de edição vamos escrever nosso Hello World!</p>
<pre class="fsharp" name="code">#light 

printfn &quot;Hello World!&quot;</pre>
<p>Com “todo” nosso código completo vamos sair do modo de edição (e voltar ao modo comando) apertando <em>ESC. </em>Para salvar e sair digitamos o comando :wq (write and quit) e enter retornando ao terminal.</p>
<p>Pra compilar nosso código fonte e gerar o primeiro .exe no Linux:</p>
<pre class="bash" name="code">fsharpc HelloWorldFSharp.fs</pre>
<p>Obtendo a resposta:</p>
<pre class="bash" name="code">Microsoft (R) F# 2.0 Compiler build 2.0.0.0
Copyright (c) Microsoft Corporation. All Rights Reserved.
tucaz@tucaz-nb:~/Workspace/HelloWorldFSharp$ ls
HelloWorldFSharp.exe  HelloWorldFSharp.fs
tucaz@tucaz-nb:~/Workspace/HelloWorldFSharp$ </pre>
<p>E por último, vamos executar nosso primeiro programa .NET em Linux:</p>
<pre class="bash" name="code">mono HelloWorldFSharp.exe
Hello World!</pre>
<p><strong>Fim!</strong></p>
<p>Neste post vimos como instalar Mono/F# no Linux e como criar nosso primeiro programa Hello World em F# utilizando o Vim. No próximo, quero começar a falar mais a respeito de F# e Vim e deixar para trás<strong>&#160;</strong>questões de ambiente.</p>
<p>Até lá!</p>
<p><strong>[1] – </strong>Estou utilizando Ubuntu 10.10 AMD64 rodando em um notebook Core i7 (2.66ghz) com 6gb de memória RAM sendo que 2gb ficam exclusivos para VM rodando no Virtual Box. A performance é ótima!</p>
<p><strong>[2] – </strong>Menu Principal –&gt; Applications –&gt; Ubuntu Software Center</p>
<p><strong>[3] –</strong> Alguma outra sugestão?</p>
<p><strong>[4]</strong> – Se o Vim não estiver instalado, basta executar “sudo apt-get install vim” para instalá-lo</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.tucaz.net/2011/01/10/comeando-a-aprender-f-com-ubuntu-mono-e-vim/feed/</wfw:commentRss>
		<slash:comments>7</slash:comments>
		</item>
		<item>
		<title>Lendo e consumindo XML com dynamic em C# 4</title>
		<link>http://blog.tucaz.net/2010/11/18/lendo-e-consumindo-xml-com-dynamic-em-c-4/</link>
		<comments>http://blog.tucaz.net/2010/11/18/lendo-e-consumindo-xml-com-dynamic-em-c-4/#comments</comments>
		<pubDate>Thu, 18 Nov 2010 23:57:30 +0000</pubDate>
		<dc:creator>tucaz</dc:creator>
				<category><![CDATA[.NET]]></category>
		<category><![CDATA[C#]]></category>

		<guid isPermaLink="false">http://blog.tucaz.net/?p=474</guid>
		<description><![CDATA[Sei que faz tempo que não posto então aqui vai um post rápido, mas com conteúdo (espero que vocês vejam dessa forma também). Finalmente comecei a trabalhar efetivamente com C# 4 e por coincidência (ou não) já precisei de dynamic objects pra resolver um problema.
Meu sistema recebe como entrada alguns arquivos XML para serem processados [...]]]></description>
			<content:encoded><![CDATA[<p>Sei que faz tempo que não posto então aqui vai um post rápido, mas com conteúdo (espero que vocês vejam dessa forma também). Finalmente comecei a trabalhar efetivamente com C# 4 e por coincidência (ou não) já precisei de dynamic objects pra resolver um problema.</p>
<p>Meu sistema recebe como entrada alguns arquivos XML para serem processados e transformados em outros objetos posteriormente. XML é um saco e é definitivamente uma das coisas que eu mais odeio em desenvolvimento de software. Tudo com XML é trabalhoso. Sendo assim criei uma pequena Lib que transforma XML em objetos dinamicos pra eliminar a necessidade de lidar com nós e atributos diretamentes e também permitir futuras implementacões.</p>
<p>Com XmlToObjectParser é possível:</p>
<pre class="xml" name="code">
&lt;?xml version="1.0" encoding="ISO-8859-1"?&gt;
&lt;catalog&gt;
  &lt;cd country="USA"&gt;
    &lt;title&gt;Empire Burlesque&lt;/title&gt;
    &lt;artist&gt;Bob Dylan&lt;/artist&gt;
    &lt;price&gt;10.90&lt;/price&gt;
  &lt;/cd&gt;
  &lt;cd country="UK"&gt;
    &lt;title&gt;Hide your heart&lt;/title&gt;
    &lt;artist&gt;Bonnie Tyler&lt;/artist&gt;
    &lt;price&gt;10.0&lt;/price&gt;
  &lt;/cd&gt;
  &lt;cd country="USA"&gt;
    &lt;title&gt;Greatest Hits&lt;/title&gt;
    &lt;artist&gt;Dolly Parton&lt;/artist&gt;
    &lt;price&gt;9.90&lt;/price&gt;
  &lt;/cd&gt;
&lt;/catalog&gt;
</pre>
<pre class="csharp" name="code">
var numberOfCDsinCatalog = catalog.catalog.cd.Count; //Retorna 3
var titleFromUKCD = catalog.catalog.cd[1].title; // Retorna "Hide your heart"
</pre>
<p>Bem mais legível e prático de usar, na minha opinião.</p>
<p>O <a href="https://github.com/tucaz/XmlToObjectParser">projeto</a> e a <a href="https://github.com/downloads/tucaz/XmlToObjectParser/XmlToObjectParser-1.0.zip">DLL compilada</a> estão no GitHub assim como a <a href="https://github.com/tucaz/XmlToObjectParser/wiki/Getting-Started">documentacão e informacões adicionais</a>.</p>
<p>Enjoy! <img src='http://blog.tucaz.net/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </p>
]]></content:encoded>
			<wfw:commentRss>http://blog.tucaz.net/2010/11/18/lendo-e-consumindo-xml-com-dynamic-em-c-4/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>Performance: NHibernate versus ADO.NET</title>
		<link>http://blog.tucaz.net/2010/08/31/performance-nhibernate-versus-ado-net/</link>
		<comments>http://blog.tucaz.net/2010/08/31/performance-nhibernate-versus-ado-net/#comments</comments>
		<pubDate>Wed, 01 Sep 2010 01:18:21 +0000</pubDate>
		<dc:creator>tucaz</dc:creator>
				<category><![CDATA[Banco de Dados]]></category>
		<category><![CDATA[C#]]></category>
		<category><![CDATA[NHibernate]]></category>
		<category><![CDATA[adhoc]]></category>
		<category><![CDATA[ADO.NET]]></category>
		<category><![CDATA[cache]]></category>
		<category><![CDATA[performance]]></category>
		<category><![CDATA[stored procedures]]></category>

		<guid isPermaLink="false">http://blog.tucaz.net/?p=466</guid>
		<description><![CDATA[Disclaimer
Os testes neste post apresentados não representam uma amostra exata ou fidedigna que represente uma condição real de acesso a dados de uma aplicação a fim de comparar a performance das duas tecnologias. A idéia é apenas mostrar alguns dados e exemplos com o objetivo de dismistificar a idéia de que ORM é uma ferramenta [...]]]></description>
			<content:encoded><![CDATA[<h1><em><span style="color: #ff0000">Disclaimer</span></em></h1>
<p><em><span style="color: #ff0000">Os testes neste post apresentados não representam uma amostra exata ou fidedigna que represente uma condição real de acesso a dados de uma aplicação a fim de comparar a performance das duas tecnologias. A idéia é apenas mostrar alguns dados e exemplos com o objetivo de dismistificar a idéia de que ORM é uma ferramenta lenta e estes testes são apenas um exercício.</span></em></p>
<p><em><span style="color: #ff0000">Sou usuário de NHibernate e defendo o uso de ORM’s portanto as conclusões apresentadas com certeza não são as mais imparciais possíveis.</span></em></p>
<p>Motivado <a title="DDD - Objetos de consulta usando ORM - o que vcs acham? @ DotNetArchitects" href="http://groups.google.com/group/dotnetarchitects/browse_thread/thread/dc01630511ec34ec">por esta thread no DNA hoje</a> decidi fazer alguns testes de perfomance pra comparar acesso a dados utilizando ADO.NET nativo (queries AdHoc e Stored Procedures) versus NHibernate.</p>
<p>Sempre rolam diversas discussões a respeito do assunto e a conclusão que geralmente se chega é de que qualquer ORM vai ser mais lento do que uma chamada nativa. É uma conclusão óbvia já que utilizar um ORM é adicionar uma camada de abstração a mais dentro da nossa aplicação. No entanto, até então eu nunca havia efetuado nenhuma medição pra ver qual a diferença de performance.</p>
<p>Todos os testes foram executados na minha máquina com código compilado em modo Release com banco de dados Sql Server 2008 também local.</p>
<p>Vamos aos testes.</p>
<h1>Cenário de testes</h1>
<p>Criei uma tabela (Product) e populei com cerca de 500 registros vindos do AdventureWorks (banco de dados exemplo do SqlServer).</p>
<p><a href="http://blog.tucaz.net/wp-content/uploads/2010/08/image.png"><img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="Modelo de Dados" border="0" alt="Modelo de Dados" src="http://blog.tucaz.net/wp-content/uploads/2010/08/image_thumb.png" width="237" height="175" /></a></p>
<p>Contra essa tabela executei duas categorias de testes:</p>
<ol>
<li>Carregar todos os registros da tabela em um List&lt;&gt; </li>
<li>Carregar apenas um registro </li>
</ol>
<p>Pra ficar mais interessante fiz algumas variações dos testes:</p>
<ul>
<li>Query AdHoc/Inline </li>
<li>Query AdHoc/Inline com hidratação<strong>[1]</strong> via reflection </li>
<li>Query utilizando uma procedure </li>
<li>NHibernate com LINQ </li>
<li>NHibernate com HQL </li>
<li>NHibernate com Criteria </li>
<li>Nhibernate com Projections </li>
</ul>
<p>Como rodando uma única vez não foi possível obter dados suficientes, executei cada teste dentro de um loop com 1000 (numberOfIterations = 1000) iterações que resultou no código abaixo:</p>
<p>Método principal:</p>
<pre class="csharp" name="code">static void Main(string[] args)
{
    for (int i = 1; i &lt;= 3; i++)
    {
        Console.WriteLine(&quot;Test &quot; + i.ToString());
        Console.WriteLine(&quot;======================&quot;);

        SqlAdHocAllProducts();
        SqlAdHocAllProductsWithReflection();
        SProcAllProducts();
        NHibernateAllProductsWithLinq();
        NHibernateAllProductsWithHql();
        NHibernateAllProductsWithCriteria();
        NHibernateAllProductsWithProjections();

        SqlAdHocOneProduct();
        SqlAdHocOneProductWithReflection();
        SProcOneProduct();
        NHibernateOneProduct();

        Console.WriteLine();
    }

    Console.ReadLine();
}</pre>
<p>
  <br />Um dos métodos usando Sql AdHoc e outro usando NHibernate:</p>
<p></p>
<pre class="csharp" name="code">private static void SqlAdHocAllProducts()
{
    List&lt;Product&gt; allProducts = null;

    var connectionString = &quot;Data Source=(local);Integrated Security=SSPI;Database=TDC2010;&quot;;
    var select = @&quot;SELECT P.Id, P.Description, P.Name, P.Price FROM dbo.Product P&quot;;

    var connection = new SqlConnection(connectionString);
    connection.Open();

    Stopwatch watch = new Stopwatch();
    watch.Start();

    for (int i = 0; i &lt; numberOfIterations; i++)
    {
        allProducts = new List&lt;Product&gt;();
        var command = new SqlCommand(select, connection);
        var reader = command.ExecuteReader();

        while (reader.Read())
        {
            allProducts.Add(new Product()
                {

                    Id = Convert.ToInt32(reader[&quot;Id&quot;]),
                    Name = Convert.ToString(reader[&quot;Name&quot;]),
                    Description = Convert.ToString(reader[&quot;Description&quot;]),
                    Price = Convert.ToDecimal(reader[&quot;price&quot;])
                });
        }

        reader.Close();
    }

    watch.Stop();

    connection.Close();
    connection.Dispose();

    Console.WriteLine(
        &quot;Loading &quot; + allProducts.Count + &quot; Products with Sql AdHoc took &quot; + watch.ElapsedMilliseconds + &quot; ms&quot;);
}</pre>
<p>
  </p>
<pre class="csharp" name="code">private static void NHibernateAllProductsWithLinq()
{
    List&lt;Product&gt; allProducts = null;

    var session = CreateForSqlServer().OpenSession();

    Stopwatch watch = new Stopwatch();
    watch.Start();

    for (int i = 0; i &lt; numberOfIterations; i++)
    {
        allProducts = session.Linq&lt;Product&gt;().ToList();
    }

    watch.Stop();

    session.Close();

    Console.WriteLine(
        &quot;Loading &quot; + allProducts.Count + &quot; Products with NHibernate took &quot; + watch.ElapsedMilliseconds + &quot; ms&quot;);
}</pre>
<p><strong>Vou omitir o restante dos métodos para evitar duplicações já que eles são apenas variações dos dois exemplos acima.</strong></p>
<h1>Resultado Geral</h1>
<p><a href="http://blog.tucaz.net/wp-content/uploads/2010/08/image1.png"><img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="Resultados dos Testes" border="0" alt="Resultados dos Testes" src="http://blog.tucaz.net/wp-content/uploads/2010/08/image_thumb1.png" width="681" height="648" /></a></p>
<h1>Análise dos Resultados</h1>
<h3>Stored Procedures versus Queries AdHoc/Inline [500 registros]</h3>
<p>A diferença entre o uso de stored procedures e queries AdHoc é praticamente inexistente. A diferença média medida foi de <strong>menos de 1%</strong>.</p>
<p>Isso acontece, pois não existe complexidade suficiente neste tipo de query para que a armazenagem do plano de execução no banco de dados faça diferença.</p>
<p>Portanto, na grande maioria dos cenários Stored Procedures não são necessárias.</p>
<h3>NHibernate versus NHibernate [500 registros]</h3>
<p>Na média, todas as variações de consulta utilizando NHibernate também tiveram <strong>mais ou menos o mesmo resultado (~1500ms)</strong> com exceção do uso de <strong>Projections</strong>, que levou o dobro<strong> (~3000ms)</strong> do tempo.</p>
<p>Não conheço o NHibernate suficiente pra afirmar com 100% de certeza o motivo, mas acredito que seja pelo fato de esse tipo de query retornar Arrays bidimensionais que são criados e redimensionados em runtime até que todos os itens possam ser acomodados.</p>
<h3>NHibernate versus ADO.NET [500 registros]</h3>
<p>Este e o comparativo mais importante. Carregando (e hidratando) 500 registros o ADO.NET é cerca de <strong>30% mais</strong> rapido do que o NHibernate. A causa dessa discrepância é uma só e se chama reflection.</p>
<p>Apesar de todas as otimizações o NHibernate utiliza-se de reflection para efetuar a hidratação<strong>[1] </strong>de todos os objetos e é dai que vem a queda de performance que fica clara quando executamos queries AdHoc usando hidratação via reflection conforme o código abaixo.</p>
<pre class="csharp" name="code">private static void SqlAdHocAllProductsWithReflection()
{
    List&lt;Product&gt; allProducts = null;

    var connectionString = &quot;Data Source=(local);Integrated Security=SSPI;Database=TDC2010;&quot;;
    var select = @&quot;SELECT P.Id, P.Description, P.Name, P.Price FROM dbo.Product P&quot;;

    var connection = new SqlConnection(connectionString);
    connection.Open();

    Stopwatch watch = new Stopwatch();
    watch.Start();

    for (int i = 0; i &lt; numberOfIterations; i++)
    {
        allProducts = new List&lt;Product&gt;();
        var command = new SqlCommand(select, connection);
        var reader = command.ExecuteReader();

        while (reader.Read())
        {
            var newProduct = Activator.CreateInstance&lt;Product&gt;();
            SetProperty(newProduct, &quot;Id&quot;, Convert.ToInt32(reader[&quot;Id&quot;]));
            SetProperty(newProduct, &quot;Description&quot;, Convert.ToString(reader[&quot;Description&quot;]));
            SetProperty(newProduct, &quot;Name&quot;, Convert.ToString(reader[&quot;Name&quot;]));
            SetProperty(newProduct, &quot;Price&quot;, Convert.ToDecimal(reader[&quot;Price&quot;]));
            allProducts.Add(newProduct);
        }

        reader.Close();
    }

    watch.Stop();

    connection.Close();
    connection.Dispose();

    Console.WriteLine(
&quot;Loading &quot; + allProducts.Count + &quot; Products with Sql AdHoc and Reflection took &quot; + watch.ElapsedMilliseconds + &quot; ms&quot;);
}

private static void SetProperty(object instance, string property, object val)
{
    Type t = instance.GetType();
    var prop = t.GetProperty(property, BindingFlags.Instance | BindingFlags.Public);
    prop.SetValue(instance, val, null);
}</pre>
<p>Este código quando executado demora cerca de <strong>6000ms, ou 4 vezes mais</strong>, do que o código executado pelo NHibernate.</p>
<p>Mas por que a diferença não é de 30%? Porque o NHibernate possui otimizações quanto ao modo de hidratar um objeto via reflection. No meu código acima podemos ver, por exemplo, que toda vez que chamo o método SetProperty o Type da propriedade a ser refletida ainda não está criado. Provavelmente o NHibernate deve manter cache deste tipo de informação (e de outras) a fim de otimizar o processo de hidratação das entidades.</p>
<h3>Stored Procedures versus Queries AdHoc/Inline [1 registro]</h3>
<p>Mesmo resultado do cenário onde 500 registros são carregados. Não há diferença.</p>
<h3>NHibernate versus ADO.NET [1 registro]</h3>
<p>Aqui a diferença é gigantesca sendo de <strong>quase 4000% a favor do NHibernate. </strong>Isso acontece, pois o NHibernate implementa cache nível 1 nativamente então dentro de uma mesma ISession o objeto é carregado apenas uma vez enquanto com ADO.NET é necessário ir ao banco e carregar o objeto diversas vezes.</p>
<h1>Conclusões</h1>
<p>Olhando para os números apenas, em casos onde diversos registros precisam ser carregados, ADO.NET nativo oferece uma performance superior e parece ser a escolha óbvia. No entanto:</p>
<ul>
<li>Os testes com NHibernate foram executados utilizandos exemplos simples e sem qualquer tipo de otimização. </li>
<li>NHibernate oferece nativamente cache de resultados de queries e cache nível 2 que se utilizados iriam exibir um resultado bem próximo ao cenário “<em>NHibernate versus ADO.NET [1 registro]” </em>onde o NHibernate é 4 vezes mais rápido. </li>
<li>ADO.NET oferece um custo de desenvolvimento e manutenção altissimo e este custo torna-se ainda maior se utilizado com Stored Procedures que transformam o cenário em algo totalmente caótico de gerenciar devido a dificuldade de manter a rastreabilidade desses diabinhos malignos. </li>
</ul>
<p>No caso de sistemas <a title="OLTP @ Wikipedia" href="http://pt.wikipedia.org/wiki/OLTP">OLTP</a> onde as transações carregam unidades individuais e/ou pequenas coleções de entidades por sessão, NHibernate não só é mais rápido como também oferece muito mais flexibilidade pra lidar com praticamente todos os cenários existentes. <a title="25 reasons not to write your own ORM @ Ayende&#39;s Blog" href="http://ayende.com/Blog/archive/2006/05/12/25ReasonsNotToWriteYourOwnObjectRelationalMapper.aspx">Este post do Ayende</a> mostra 25 funcionalidades importantes (cache, gerenciamento de concorrência, etc) que você vai precisar quando estiver lidando com dados e que custariam muito caro (tempo e complexidade) caso você queira escreve-las “na mão”.</p>
<p>Em cenários de aplicações de internet onde o número de leituras é infinitamente superior ao número de escritas no banco de dados deve se utilizar cache no front end (IIS), portanto o tempo que se leva pra montar uma página é irrelevante. Mesmo que você carregasse os dados de um servidor remoto via conexão discada não faria diferença uma vez que os dados estivessem em cache.</p>
<p>Por último, se você se encontrar em uma situação utilizando NHibernate onde o acesso a dados é o gargalo da sua aplicação seu problema não é o NHibernate (a não ser que você tenha usado-o de maneira totalmente absurda, mas a probabilidade de você fazer o mesmo com ADO.NET é grande também). Nestes cenários o problema não é o acesso a dados em si, mas o resto da arquitetura que não escala de maneira adequada seja por meio de cache, processamento assincrono, filas, etc.</p>
<p>Sendo assim, acredito que podemos concluir que não faz sentido algum no meio do ano de 2010 utilizar queries AdHoc ou Stored Procedures em aplicações <a title="Line of Business @ Wikipedia" href="http://en.wikipedia.org/wiki/Line_of_business">LoB</a>. <img src='http://blog.tucaz.net/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </p>
<p>O código completo utilizado está no GitHub e pode ser <a title="NHPerf Source Code @ GitHub" href="http://github.com/tucaz/Samples/tree/master/NHPerf/">acessado online</a> ou baixado em <a title="Download of NHPerf Source Code @ GitHub" href="http://github.com/downloads/tucaz/Samples/NHPerf.zip">formato zip</a>.</p>
<p><strong>[1] – Hidratação é o processo de preenchimento (filling) das propriedades de uma entidade</strong></p>
]]></content:encoded>
			<wfw:commentRss>http://blog.tucaz.net/2010/08/31/performance-nhibernate-versus-ado-net/feed/</wfw:commentRss>
		<slash:comments>17</slash:comments>
		</item>
		<item>
		<title>Material da palestra no TDC2010 &#8211; ORM: Por que isso te interessa?</title>
		<link>http://blog.tucaz.net/2010/08/26/material-da-palestra-no-tdc2010-orm-por-que-isso-te-interessa/</link>
		<comments>http://blog.tucaz.net/2010/08/26/material-da-palestra-no-tdc2010-orm-por-que-isso-te-interessa/#comments</comments>
		<pubDate>Thu, 26 Aug 2010 22:09:38 +0000</pubDate>
		<dc:creator>tucaz</dc:creator>
				<category><![CDATA[.NET]]></category>
		<category><![CDATA[Apresentações]]></category>
		<category><![CDATA[NHibernate]]></category>
		<category><![CDATA[dao]]></category>
		<category><![CDATA[data access]]></category>
		<category><![CDATA[Evento]]></category>
		<category><![CDATA[orm]]></category>
		<category><![CDATA[Palestras]]></category>
		<category><![CDATA[slides]]></category>
		<category><![CDATA[tdc2010]]></category>

		<guid isPermaLink="false">http://blog.tucaz.net/?p=459</guid>
		<description><![CDATA[
No último fim de semana rolou em São Paulo o TDC2010 organizado pela Globalcode. Fui convidado a palestrar na trilha de .NET pelo @giovannibassi pra falar um pouquinho sobre ORM e porque é uma boa idéia usá-lo.
Abaixo estão os slides da minha palestra, que não fazem muito sentido por si só, mas que tem umas [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://blog.tucaz.net/wp-content/uploads/2010/08/barratopbasic.jpg"><img style="display: inline; border-width: 0px;" title="barra-top-basic" src="http://blog.tucaz.net/wp-content/uploads/2010/08/barratopbasic_thumb.jpg" border="0" alt="barra-top-basic" width="390" height="68" /></a></p>
<p>No último fim de semana rolou em São Paulo o <a href="http://www.thedevelopersconference.com.br/">TDC2010</a> organizado pela <a href="http://www.globalcode.com.br">Globalcode</a>. Fui convidado a palestrar na <a href="http://www.thedevelopersconference.com.br/tdc/2010/sp/trilha-dot-net">trilha de .NET</a> pelo <a href="http://www.twitter.com/giovannibassi">@giovannibassi</a> pra falar um pouquinho sobre ORM e porque é uma boa idéia usá-lo.</p>
<p>Abaixo estão os <a href="http://www.slideshare.net/tucaz/orm-por-que-isso-te-interessa-tdc2010/">slides da minha palestra</a>, que não fazem muito sentido por si só, mas que tem umas imagens divertidas!</p>
<div id="__ss_5047644" style="width: 425px;"><strong><a title="ORM: Por que isso te interessa? (TDC2010)" href="http://www.slideshare.net/tucaz/orm-por-que-isso-te-interessa-tdc2010">ORM: Por que isso te interessa? (TDC2010)</a></strong><object id="__sse5047644" classid="clsid:d27cdb6e-ae6d-11cf-96b8-444553540000" width="425" height="355" codebase="http://download.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=6,0,40,0"><param name="allowFullScreen" value="true" /><param name="allowScriptAccess" value="always" /><param name="src" value="http://static.slidesharecdn.com/swf/ssplayer2.swf?doc=orm-100824141739-phpapp01&amp;stripped_title=orm-por-que-isso-te-interessa-tdc2010" /><param name="name" value="__sse5047644" /><param name="allowfullscreen" value="true" /><embed id="__sse5047644" type="application/x-shockwave-flash" width="425" height="355" src="http://static.slidesharecdn.com/swf/ssplayer2.swf?doc=orm-100824141739-phpapp01&amp;stripped_title=orm-por-que-isso-te-interessa-tdc2010" name="__sse5047644" allowscriptaccess="always" allowfullscreen="true"></embed></object></p>
<div style="padding-bottom: 12px; padding-left: 0px; padding-right: 0px; padding-top: 5px;">View more <a href="http://www.slideshare.net/">presentations</a> from <a href="http://www.slideshare.net/tucaz">tucaz</a>.</div>
</div>
<p>Em um dos últimos slides tem uma porção de links muito legais sobre NHibernate então pra quem não quiser ter o trabalho de ver os slides ai vai:</p>
<p><span style="text-decoration: underline;"><a href="http://nhforge.org/">http://nhforge.org/</a></span> -&gt; NHibernate official website<br />
<span style="text-decoration: underline;"><a href="http://fluentnhibernate.org/">http://fluentnhibernate.org/</a></span> -&gt; Fluent Mappings for Nhibernate<br />
<span style="text-decoration: underline;"><a href="http://nhprof.com/">http://nhprof.com/</a></span> -&gt; NHibernate Profiler with 30 day trial<br />
<span style="text-decoration: underline;"><a href="http://www.summerofnhibernate.com/">http://www.summerofnhibernate.com/</a></span> -&gt; More than 14 hours of free videos<br />
<span style="text-decoration: underline;"><a href="http://www.manning.com/kuate/">http://www.manning.com/kuate/</a> </span>-&gt; “NHibernate In Action” Book by Manning<br />
<span style="text-decoration: underline;"><a href="http://ayende.com/Blog/category/510.aspx">http://ayende.com/Blog/category/510.aspx</a></span><span style="text-decoration: underline;"> </span>-&gt; NHibernate @ Ayende’s<br />
<span style="text-decoration: underline;"><a href="http://tinyurl.com/25reasons">http://tinyurl.com/25reasons</a></span> -&gt; 25 reasons NOT to write yout own ORM @ Ayende’s<br />
<a href="http://fabiomaulo.blogspot.com/search/label/NHibernate">http://fabiomaulo.blogspot.com/search/label/NHibernate</a> -&gt; NHibernate @ Fabio Maulo’s<br />
<a href="http://blogs.hibernatingrhinos.com/nhibernate/">http://blogs.hibernatingrhinos.com/nhibernate/</a> -&gt; NHibernate Blog<br />
<span style="text-decoration: underline;"><a href="http://code.google.com/p/unhaddins/">http://code.google.com/p/unhaddins/</a></span> -&gt; unhaddins, Unofficial addins for Nhibernate</p>
<p>Além dos slides, <a href="http://github.com/tucaz/Samples">coloquei no GitHub também o código fonte do projetinho que usei na demo que fiz</a>. Apesar de ser uma demo, o código serve como referência pra começar a utilizar o NHibernate e FluentMapping e ter uma idéia de algumas features bem legais que ele oferece.</p>
<p><a href="http://github.com/downloads/tucaz/Samples/TDC2010.zip">Download do zip com o código.</a></p>
<p>Palestraram também, da Stefanini, <a href="http://www.twitter.com/vquaiato">@vquaiato</a> na trilha de Ruby e .NET, <a href="http://www.twitter.com/alnascimento">@alnascimento</a> e <a href="http://www.twitter.com/manoelp">@manoelp</a> em Agile, <a href="http://www.twitter.com/vcavalcante">@vcavalcante</a> em .NET e <a href="http://www.twitter.com/jorgediz">@jorgediz</a> em Testes.</p>
<p>Por último, mas não menos importante eu queria deixar registrado meu agradecimento ao <a href="http://ayende.com/">Oren Eini (a.k.a. Ayende Rahien</a>) pelos cupons de desconto e licensa do <a href="http://nhprof.com/">NHProf</a> que distribui ao final da palestra e também a Candace da <a href="http://www.manning.com/">Manning Publications</a> pelas cópias dos eBooks “<a href="http://www.manning.com/kuate/">NHibernate In Action</a>” que também dei de brinde. Muito obrigado pelas contribuições a comunidade! <img src='http://blog.tucaz.net/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </p>
<p>Now in English so I can make this public to English speakers too. Thanks to <a href="http://ayende.com/">Oren Eini (a.k.a Ayende Rahien</a>) for the discount coupons and <a href="http://nhprof.com/">NHProf</a> license that I gave out and to Candace from <a href="http://www.manning.com/">Manning Publications</a> for the copies of “<a href="http://www.manning.com/kuate/">NHibernate In Action</a>” that were also given at the event. You guys are amazing. Thanks a lot for contributing with this growing community! <img src='http://blog.tucaz.net/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </p>
]]></content:encoded>
			<wfw:commentRss>http://blog.tucaz.net/2010/08/26/material-da-palestra-no-tdc2010-orm-por-que-isso-te-interessa/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>(Inglês) Basic stuff: handling exceptions in .NET</title>
		<link>http://blog.tucaz.net/2009/07/21/basic-stuff-handling-exceptions-in-net/</link>
		<comments>http://blog.tucaz.net/2009/07/21/basic-stuff-handling-exceptions-in-net/#comments</comments>
		<pubDate>Tue, 21 Jul 2009 18:19:09 +0000</pubDate>
		<dc:creator>tucaz</dc:creator>
				<category><![CDATA[.NET]]></category>
		<category><![CDATA[Arquitetura]]></category>
		<category><![CDATA[C#]]></category>
		<category><![CDATA[Desenvolvimento]]></category>
		<category><![CDATA[exception]]></category>
		<category><![CDATA[handling]]></category>
		<category><![CDATA[vb.net]]></category>

		<guid isPermaLink="false">http://blog.tucaz.net/?p=336</guid>
		<description><![CDATA[(Inglês) A simple guide on How to build proper exception handling in .NET.]]></description>
			<content:encoded><![CDATA[<p>Desculpe, mas este post só está disponível em <a href="http://blog.tucaz.net/en/category/desenvolvimento/net/feed/">Inglês</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.tucaz.net/2009/07/21/basic-stuff-handling-exceptions-in-net/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>Ruby on Rails e WinDBG</title>
		<link>http://blog.tucaz.net/2009/04/03/ruby-on-rails-e-windbg/</link>
		<comments>http://blog.tucaz.net/2009/04/03/ruby-on-rails-e-windbg/#comments</comments>
		<pubDate>Sat, 04 Apr 2009 02:46:39 +0000</pubDate>
		<dc:creator>tucaz</dc:creator>
				<category><![CDATA[.NET]]></category>
		<category><![CDATA[Desenvolvimento]]></category>
		<category><![CDATA[Dicas]]></category>
		<category><![CDATA[RoR]]></category>
		<category><![CDATA[debug]]></category>
		<category><![CDATA[rails]]></category>
		<category><![CDATA[ruby]]></category>
		<category><![CDATA[windbg]]></category>

		<guid isPermaLink="false">http://blog.tucaz.net/?p=273</guid>
		<description><![CDATA[Dicas a respeito de Windows Debugging e Ruby on Rails]]></description>
			<content:encoded><![CDATA[<p>Não, não, não! Uma coisa não tem nada a ver com a outra. Não é um post falando de como debuggar rails utilizando o WinDBG. Mas um único post dando dicas de boas referências sobre o assunto.</p>
<p>Ultimamente não tenho mexido muito em código. Na verdade não tenho visto nada técnico, pois estou atolado de propostas pra fazer (quem mandou não estudar? <img src='http://blog.tucaz.net/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' />  ). Mas&#8230;hoje quando cheguei em casa decidi que iria dedicar algum tempinho para mexer em algo interessante e diferente. Foi ai que topei primeiro com rails que eu já queria começar a estudar e depois com o WinDBG numa dica que veio do Twitter do <a title="André Nobre no Twitter" href="http://twitter.com/nbrtec" target="_self">André Nobre</a>.</p>
<p><strong>Ruby on Rails</strong></p>
<p>Há alguns dias instalei o ubuntu em uma VM aqui em casa e montei todo o ambiente Rails para começar a fuçar. Apesar de ainda não ter concluído e contrariando as dicas do <a title="Blog Rafael Rosa" href="http://www.rafaelrosafu.com/" target="_self">Rafael Rosa</a> que disse para eu fazer algo mais simples, iniciei a construção de um programinha de FTP web em Rails. Na verdade, hoje eu parei num &#8220;Hello World&#8221;. De qualquer forma, para quem está curioso para começar a mexer e ver o poder da ferramenta decidi disponibilizar alguns links que eu já havia encontrado e que o Rafa me passou. Ai vai:</p>
<ul>
<li><a title="Ruby Inside - Maior portal Brasileiro de notícias sobre Ruby" href="http://www.rubyinside.com.br/" target="_self">RubyInside</a> &#8211; Maior portal Brasileiro sobre notícias de Ruby. Primo do site gringo <a title="RubyInside.com" href="http://www.rubyinside.com" target="_self">http://www.rubyinside.com</a>.</li>
<li><a title="RailsCasts - Screencasts gratuitos sobre Rails" href="http://railscasts.com/" target="_self">RailsCasts</a> &#8211; Diversos screencasts gratuitos a respeito de Rails. Cobre diversos assuntos com exemplos.</li>
<li><a title="RubyQuickRef" href="http://www.zenspider.com/Languages/Ruby/QuickRef.html" target="_self">RubyQuickRef</a> &#8211; Site contendo uma referência rápida as classes de Ruby.</li>
<li><a title="Rails Guides" href="http://guides.rubyonrails.org/" target="_self">Rails Guides</a> &#8211; Segundo o Rafa, site que contém guias obrigatórios para os Railers que além de ensinar a programar em RoR, ensina &#8220;in the rails way&#8221;.</li>
<li><a title="RoR API Documentation" href="http://api.rubyonrails.org/" target="_self">Rails API</a> &#8211; Toda documentação da API do Rails.</li>
<li><a title="Ruby API Documentation" href="http://www.ruby-doc.org/core/" target="_self">Ruby API</a> &#8211; Toda documentação da API do Ruby.</li>
<li>Micro-tutorial Rails <a title="AkitaOnRails - Micro-tutorial Ruby Parte 1" href="http://www.akitaonrails.com/2008/11/10/micro-tutorial-de-ruby-parte-i" target="_self">Parte 1</a>, <a title="AkitaOnRails - Micro-tutorial Ruby Parte 2" href="http://www.akitaonrails.com/2008/11/10/micro-tutorial-de-ruby-parte-ii" target="_self">Parte 2</a> e <a title="AkitaOnRails - Micro-tutorial Ruby Parte 3" href="http://www.akitaonrails.com/2008/11/10/micro-tutorial-de-ruby-parte-iii" target="_self">Parte 3</a> &#8211; Micro-tutorial sobre Ruby no blog do AkitaOnRails. Desde o básico até alguns conceitos avançados.</li>
<li><a title="Montando ambiente Rails em Windows - AkitaOnRails" href="http://www.akitaonrails.com/2009/01/12/o-melhor-ambiente-windows-para-rails" target="_self">Montando ambiente Rails em Windows</a> &#8211; Tutorial ensinando a montar o melhor ambiente Rails em Windows também do AkitaOnRails.</li>
<li><a title="Blog Rafael Rosa" href="http://www.rafaelrosafu.com/" target="_self">Blog do Rafael Rosa</a> &#8211; Várias coisas a respeito de Rails e também de Asp.NET MVC <img src='http://blog.tucaz.net/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </li>
</ul>
<p>Esses são só alguns. Com certeza tem muito mais e espero colocar mais informações a respeito de Rails conforme eu for mexendo!</p>
<p><strong>WinDBG</strong></p>
<p>Debuggar código é uma arte. As vezes mais difícil do que criar código do zero. Afinal, quando debuggamos código que não é nosso temos que entender o que quer dizer e as vezes é tão mau escrito que é triste de ver&#8230;</p>
<p>Além do debug que estamos acostumados, dentro do VS existem debugs mais baixo nível que podemos fazer. Lá na CLR e no Windows, quando as fronteiras já passaram nossa aplicação. Praticamente coisa de louco!</p>
<p>Não é um assunto simples, nem tão pouco fácil de aprender. Há alguns meses navegando nos blogs da Microsoft encontrei o blog da <a title="Tess Fernandes Blog" href="http://blogs.msdn.com/tess/" target="_self">Tess Fernandes</a> que é engenheira da Microsoft. A menina é du mau e ela fala basicamente de debugging e assuntos relacionados a performance. O problema é que muito dos tópicos sobre debug que ela aborda são muito avançados para newbies como eu.</p>
<p>Ai é onde entra o blog do <a title="Blog do André Nobre" href="http://weblogs.asp.net/andrenobre/" target="_self">André Nobre</a> que já tem <a title="WinDBG - Série de posts sobre o assunto" href="http://weblogs.asp.net/andrenobre/archive/tags/WinDBG/default.aspx" target="_self">diversos posts</a> em português e em um nível iniciante para ajudar as mentes mais ignorantes neste assunto como é meu caso. Alguns dos posts inclusive são em formato de screencast com demos. Vale a pena conferir para aprofundar um pouquinho mais nesse assunto e conhecer uma outra alternativa para descobrir porque aquela maravilhosa aplicação que desenvolvemos não funciona como deveria. <img src='http://blog.tucaz.net/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </p>
<p>Enjoy!</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.tucaz.net/2009/04/03/ruby-on-rails-e-windbg/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Como gerenciar versões de banco de dados &#8211; Parte 1</title>
		<link>http://blog.tucaz.net/2009/03/01/como-gerenciar-versoes-de-banco-de-dados-parte-1/</link>
		<comments>http://blog.tucaz.net/2009/03/01/como-gerenciar-versoes-de-banco-de-dados-parte-1/#comments</comments>
		<pubDate>Sun, 01 Mar 2009 19:19:52 +0000</pubDate>
		<dc:creator>tucaz</dc:creator>
				<category><![CDATA[.NET]]></category>
		<category><![CDATA[Banco de Dados]]></category>
		<category><![CDATA[Controle de Versão]]></category>
		<category><![CDATA[CVS]]></category>
		<category><![CDATA[Database]]></category>
		<category><![CDATA[SqlServer]]></category>
		<category><![CDATA[SVN]]></category>
		<category><![CDATA[TFS]]></category>
		<category><![CDATA[VSS]]></category>

		<guid isPermaLink="false">http://blog.tucaz.net/?p=250</guid>
		<description><![CDATA[Gerenciando versões de banco de dados de sistemas e produtos em desenvolvimento de software por meio do Migrator.NET.]]></description>
			<content:encoded><![CDATA[<p>Quando estamos desenvolvendo software, seja ele um produto com desenvolvimento contínuo (como o Wordpress, por exemplo) ou um sistema<strong> </strong>customizado para um cliente nos deparamos com um problema no mínimo chato de resolver: gerenciar as versões do banco de dados (tabelas, procedures, etc) que evoluem ao longo do projeto. Vou apresentar a  vocês em um artigo com duas partes uma solução que tem me trazido paz e segurança nos últimos tempos e que talvez possa te ajudar também.</p>
<p><strong>O problema</strong></p>
<p>Controlar o código fonte que é compilado pela nossa ferramenta de trabalho é uma tarefa que já foi bem complicada, mas que se tornou relativamente fácil com a evolução dos próprios editores de código (Visual Studio) e dos repositórios de código (<a title="Team Foundation Server" href="http://msdn.microsoft.com/en-us/teamsystem/dd408382.aspx" target="_self">TFS</a>, <a title="Subversion" href="http://subversion.tigris.org/" target="_self">SVN</a>, <a title="Concurrent Version System" href="http://www.nongnu.org/cvs/" target="_self">CVS</a>, etc). No entanto, não podemos dizer o mesmo dó código fonte que utilizamos para nossa aplicação acessar  bancos de dados. Na maioria da vezes esse código não é compilado e por mais que existam checagens de sintaxe os erros tendem a aparecer na hora que estamos desenvolvendo a versão 2.1 do sistema e precisamos recuperar versão 1.5 para corrigir bugs. Isto, quando esse controle é feito de alguma forma e esse processo é possível, pois na maioria das vezes tudo que as pessoas mantém são os dados no próprio <a title="Sistemas de Gerenciamento de Banco de Dados" href="http://pt.wikipedia.org/wiki/Sistema_de_gerenciamento_de_banco_de_dados" target="_self">SGBD </a>sem nenhum controle de versão.</p>
<p>Gerenciar a versão do banco de dados quer dizer que no momento em que eu recuperar a versão XYZ do meu sistema também vou conseguir recuperar os artefatos de banco (tabelas, procedures, triggers, etc) correspondentes a esta versão, restaurando desta forma o sistema em um ponto estável tanto do ponto de vista de estrutura quanto do ponto de vista de dados.</p>
<p>Além dos pontos falhos óbvios que essa falta de controle apresenta existe mais um problema que considero grave e que, inclusive prejudica a aplicação de práticas ágeis como integração contínua e testes automatizados. Existindo a necessidade de efetuar esse controle de maneira manual fica impraticável a execução dessas práticas, pois para executá-las durante todo o tempo <strong>tudo</strong> (incluindo os scripts de banco de dados) que compõe o sistema deve permitir automatização.</p>
<p><strong>As opções existentes<br />
</strong></p>
<p>É claro que não posso falar por toda a comunidade de desenvolvimento Microsoft, mas  a grande maioria dos projetos que já participei ou conversei a respeito com outros colegas de plataforma tinha pouquissimo (não confiável) ou nenhum controle deste tipo. Geralmente as pessoas efetuam este tipo de controle de duas formas:</p>
<ul>
<li><em>Como se fosse código-fonte normal</em> &#8211; Scripts de create table, procedures e demais artefatos são mantidos em diversos arquivos SQL (ou em um linguição) no repositório de código e o desenvolvedor utiliza eles na hora em que precisa avançar ou restaurar uma versão. O maior problema desta técnica é que como o desenvolvedor não precisa efetivamente gerar scripts de banco de dados para modificar o banco, pois pode faze-lo pela ferramenta RAD com arrasta-estica-e-puxa dificilmente ele gera esses scripts depois da primeira vez e mais raramente ainda ele gera esses scripts de maneira correta. No final, temos uma salada de scripts: alguns utilizando alter table, outros modificando um script de create já existente, diversas versões da mesma procedure e possívelmente nenhum daqueles scripts de carga feitos pelo joãozinho no começo do projeto. Dessa forma, é impossível ir para a versão de banco de dados desejada de maneira fácil e sem dores de cabeça.</li>
<li><em>Mantendo tudo no banco de dados</em> &#8211; A maioria dos desenvolvedores, infelizmente, se preocupa pouquissimo com o futuro do projeto e estão preocupados apenas com suas tarefas atuais. Dessa forma, qualquer atalho para terminar uma tela mais rápido é bem vindo, mesmo que este atalho cause um grande problema no futuro. Por este motivo, muitas pessoas mantem a estrutura de banco de dados apenas no SGBD. Alguns projetos inclusive não tem nem um modelo de dados em uma ferramenta como o ErWin ou DBDesigner por exemplo. Agora vamos imaginar que por algum motivo o banco de dados de desenvolvimento foi pro espaço. Se não tiver alguém da equipe que mantem um backup local o projeto está perdido. Possívelmente milhões $$$ perdidos por preguiça e falta de organização.</li>
</ul>
<p>A Microsoft tentou no <a title="VSTS Database Edition" href="http://msdn.microsoft.com/pt-br/library/aa833253.aspx" target="_self">Visual Studio Team System Database Edition</a> com o projeto de banco de dados (somente para SqlServer) uma alternativa a essas maneiras, mas infelizmente não obteve sucesso. A idéia é manter um projeto que por meio de um banco de dados local simula a compilação dos scripts diminuindo os erros de deploy. No entanto, todo este processo é lento, obriga o desenvolvedor a ter um SqlServer instalado localmente e tem uma série de limitações como não poder acessar outros bancos diferentes do banco com qual o sistema trabalha e de outros providers (Oracle, MySql, etc.). Ainda não testei o VSTS 2010, mas não acredito que seguindo esta receita seja possível obter muito sucesso.</p>
<p><strong>A solução</strong></p>
<p>Para resolver este problema, o ideal seria que pudéssemos tratar dos objetos de banco da mesma maneira que tratamos os objetos do nosso sistema. Objetos que compilam efetivamente nos oferecem mais segurança, ainda mais se estes forem construidos utilizando uma API simples e padronizada que possibilite o deploy em bancos distintos. Melhor ainda se o desenvolvedor não precisar ter muito trabalho para efetuar este controle, pois se o processo exigir muito trabalho ninguém irá utilizá-lo.</p>
<p>No <a title="Como gerenciar versões de banco de dados - Parte 2" href="http://blog.tucaz.net/2009/03/08/como-gerenciar-versoes-de-banco-de-dados-parte-2/" target="_self">próximo post</a>, vou falar sobre o <a title="Migrator.NET" href="http://code.google.com/p/migratordotnet/" target="_self">Migrator.NET</a> que oferece essas características que apresentei no paragráfo anterior de uma maneira rápida e fácil de usar. <img src='http://blog.tucaz.net/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </p>
<p><a title="Como gerenciar versões de banco de dados - Parte 2" href="http://blog.tucaz.net/2009/03/08/como-gerenciar-versoes-de-banco-de-dados-parte-2/" target="_self">Link para parte 2</a></p>
]]></content:encoded>
			<wfw:commentRss>http://blog.tucaz.net/2009/03/01/como-gerenciar-versoes-de-banco-de-dados-parte-1/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>Integração Contínua com .NET</title>
		<link>http://blog.tucaz.net/2009/02/13/integracao-continua-com-net/</link>
		<comments>http://blog.tucaz.net/2009/02/13/integracao-continua-com-net/#comments</comments>
		<pubDate>Fri, 13 Feb 2009 18:30:09 +0000</pubDate>
		<dc:creator>tucaz</dc:creator>
				<category><![CDATA[.NET]]></category>
		<category><![CDATA[CI]]></category>
		<category><![CDATA[Cruise Control]]></category>
		<category><![CDATA[FXCop]]></category>
		<category><![CDATA[Integração Contínua]]></category>
		<category><![CDATA[MSBuild]]></category>
		<category><![CDATA[NUnit]]></category>

		<guid isPermaLink="false">http://blog.tucaz.net/?p=239</guid>
		<description><![CDATA[Guideline para implementação de processo de integração contínua]]></description>
			<content:encoded><![CDATA[<p>E o <a title="TucaZ @ Twitter" href="http://twitter.com/tucaz" target="_self">Twitter</a> já traz bons resultados! eheehe&#8230; <img src='http://blog.tucaz.net/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </p>
<p>O <a title="Bruno Caimas @ Twitter" href="http://twitter.com/brunocaimar" target="_self">Bruno </a>acabou de me passar um link excelente que vale compartilhar com vocês aqui. <a title="Guia para integração contínua" href="http://dotnet.org.za/cjlotz/archive/2008/01/15/continuous-integration-from-theory-to-practice-2nd-edition.aspx" target="_self">Um guideline criado por Carel Lotz com passo a passo para montar um processo de Integração Contínua completo!</a></p>
<p>Have fun!</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.tucaz.net/2009/02/13/integracao-continua-com-net/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Resultado da terceira reunião do grupo DotNetArchitects &#8211; Com vídeo :)</title>
		<link>http://blog.tucaz.net/2008/12/29/resultado-da-terceira-reuniao-do-grupo-dotnetarchitects-com-video/</link>
		<comments>http://blog.tucaz.net/2008/12/29/resultado-da-terceira-reuniao-do-grupo-dotnetarchitects-com-video/#comments</comments>
		<pubDate>Tue, 30 Dec 2008 00:27:55 +0000</pubDate>
		<dc:creator>tucaz</dc:creator>
				<category><![CDATA[.NET]]></category>
		<category><![CDATA[Apresentações]]></category>
		<category><![CDATA[DDD]]></category>
		<category><![CDATA[DotNetArchitects]]></category>
		<category><![CDATA[Apresentação DDD]]></category>
		<category><![CDATA[Domain Driven Design]]></category>

		<guid isPermaLink="false">http://blog.tucaz.net/?p=202</guid>
		<description><![CDATA[Vídeos e slides da apresentação sobre DDD da terceira reunião do grupo DotNetArchitects.]]></description>
			<content:encoded><![CDATA[<p>No último dia 13 tivemos a terceira reunião do <a title="DotNetArchitects" href="http://www.dotnetarchitects.net/" target="_self">grupo</a> e os resultados podem ser vistos <a title="DotNetArchitects - Resultado da terceira reunião" href="http://dotnetarchitects.net/dotnetarchitects/post/Resultado-da-terceira-reuniao-DDD.aspx" target="_self">nesse post</a>.</p>
<p>Os vídeos da apresentação do <a title="Giovanni Bassi - Blog" href="http://unplugged.giggio.net/">Giovanni</a> sobre DDD e do debate posterior também já estão disponíveis para quem não pode ir ou tem interesse no assunto assim como os slides:</p>
<p><strong>Apresentação</strong></p>
<div><object classid="clsid:d27cdb6e-ae6d-11cf-96b8-444553540000" width="400" height="362" codebase="http://download.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=6,0,40,0"><param name="id" value="VideoPlayback" /><param name="src" value="http://video.google.com/googleplayer.swf?docid=-7056786168177403020&amp;hl=pt-BR&amp;fs=true" /><embed id="VideoPlayback" type="application/x-shockwave-flash" width="400" height="362" src="http://video.google.com/googleplayer.swf?docid=-7056786168177403020&amp;hl=pt-BR&amp;fs=true"></embed></object></div>
<p><strong>Debate</strong></p>
<div><object classid="clsid:d27cdb6e-ae6d-11cf-96b8-444553540000" width="400" height="362" codebase="http://download.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=6,0,40,0"><param name="id" value="VideoPlayback" /><param name="src" value="http://video.google.com/googleplayer.swf?docid=3055016873351250860&amp;hl=pt-BR&amp;fs=true" /><embed id="VideoPlayback" type="application/x-shockwave-flash" width="400" height="362" src="http://video.google.com/googleplayer.swf?docid=3055016873351250860&amp;hl=pt-BR&amp;fs=true"></embed></object></div>
<p><strong>Slides</strong></p>
<div id="__ss_852102" style="width: 425px; text-align: left;"><a style="font:14px Helvetica,Arial,Sans-serif;display:block;margin:12px 0 3px 0;text-decoration:underline;" title="DDD &gt; Experiências" href="http://www.slideshare.net/giovanni.bassi/ddd-experincias-presentation?type=powerpoint">DDD &gt; Experiências</a><object classid="clsid:d27cdb6e-ae6d-11cf-96b8-444553540000" width="425" height="355" codebase="http://download.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=6,0,40,0"><param name="allowFullScreen" value="true" /><param name="allowScriptAccess" value="always" /><param name="src" value="http://static.slideshare.net/swf/ssplayer2.swf?doc=ddd1-copy-1229483358051446-1&amp;stripped_title=ddd-experincias-presentation" /><embed type="application/x-shockwave-flash" width="425" height="355" src="http://static.slideshare.net/swf/ssplayer2.swf?doc=ddd1-copy-1229483358051446-1&amp;stripped_title=ddd-experincias-presentation" allowscriptaccess="always" allowfullscreen="true"></embed></object></p>
<div style="font-size: 11px; font-family: tahoma,arial; height: 26px; padding-top: 2px;">View SlideShare <a style="text-decoration:underline;" title="View DDD &gt; Experiências on SlideShare" href="http://www.slideshare.net/giovanni.bassi/ddd-experincias-presentation?type=powerpoint">presentation</a> or <a style="text-decoration:underline;" href="http://www.slideshare.net/upload?type=powerpoint">Upload</a> your own. (tags: <a style="text-decoration:underline;" href="http://slideshare.net/tag/ddd">ddd</a> <a style="text-decoration:underline;" href="http://slideshare.net/tag/net">.net</a>)</div>
</div>
<p>Olha como melhoramos! Em comparação com o material da <a title="Apresentação sobre Scrum" href="http://blog.tucaz.net/2008/11/27/video-da-segunda-reuniao-dotnetarchitects-com-miinha-apresentacao-online/" target="_self">minha apresentação</a>, a gravação do áudio e vídeo já estão muito melhores.</p>
<p>Obrigado e parabéns novamente ao pessoal da UNIP que está apoiando a gente.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.tucaz.net/2008/12/29/resultado-da-terceira-reuniao-do-grupo-dotnetarchitects-com-video/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>.NET Scrum &#8211; Projeto Open Source</title>
		<link>http://blog.tucaz.net/2008/12/28/net-scrum-projeto-open-source/</link>
		<comments>http://blog.tucaz.net/2008/12/28/net-scrum-projeto-open-source/#comments</comments>
		<pubDate>Sun, 28 Dec 2008 20:16:31 +0000</pubDate>
		<dc:creator>tucaz</dc:creator>
				<category><![CDATA[.NET]]></category>
		<category><![CDATA[.NET Scrum]]></category>
		<category><![CDATA[Arquitetura]]></category>
		<category><![CDATA[C#]]></category>
		<category><![CDATA[DDD]]></category>
		<category><![CDATA[Desenvolvimento]]></category>
		<category><![CDATA[OO]]></category>
		<category><![CDATA[Scrum]]></category>
		<category><![CDATA[ASP.NET MVC]]></category>
		<category><![CDATA[Codeplex]]></category>
		<category><![CDATA[Design Patterns]]></category>
		<category><![CDATA[Fluent Interfaces]]></category>
		<category><![CDATA[jQuery]]></category>
		<category><![CDATA[MVC]]></category>
		<category><![CDATA[NHibernate]]></category>
		<category><![CDATA[open source]]></category>
		<category><![CDATA[Spring.NET]]></category>
		<category><![CDATA[TDD]]></category>
		<category><![CDATA[User Experience]]></category>

		<guid isPermaLink="false">http://blog.tucaz.net/?p=195</guid>
		<description><![CDATA[Projeto .NET open source para gerenciamente de projetos utilizando Scrum como disciplina. Boas práticas de engenharia e conducação de projetos utilizando frameworks e práticas de mercado.]]></description>
			<content:encoded><![CDATA[<p>Há poucas semanas, batendo papo com o pessoal do <a title="DotNetArchitects - Arquitetura em .NET" href="http://www.dotnetarchitects.net/" target="_self">DotNetArchitects</a>, surgiu a idéia de utilizarmos uma ferramenta de gerenciamento de projetos Scrum pra cuidar dos das nossas atividades dentro do grupo.</p>
<p>Fui pesquisar, mas não encontrei nenhuma ferramenta gratuita web que pudessemos usar. Foi ai que surgiu o <a title=".NET Scrum - Ferramenta open source de gerenciamento de projetos Scrum" href="https://www.codeplex.com/netscrum" target="_self"><strong>.NET Scrum</strong></a>. A idéia não é construir nada pra competir com o que existe por ai, mas utilizar da idéia pra ter um laboratório e construir um projeto onde possamos aplicar o que há de mais novo em tecnologia além de boas práticas de engenharia e condução de projetos.</p>
<p>Portanto, quem der uma olhada no projeto e quiser contribuir ou apenas acompanhar vai encontrar um ASP.NET MVC, jQuery, NHibernate usando interfaces fluentes, DDD, TDD, Spring.NET e outros frameworks e design patterns importantes para a construção de uma boa solução em .NET.</p>
<p>Se deixarmos de lado a parte tecnológica também é possível aprender um bocado trabalhando na organização de um projeto open source. Projetos de código aberto e mantidos pela comunidade são o maior caso de sucesso de times distribuidos trabalhando juntos a fim de atingir um objetivo. Se já é difícil obter sucesso em um projeto com o time no mesmo lugar, imagine trabalhar com pessoas que você nunca viu na vida e com comunicação relativamente limitada? Um grande desafio!</p>
<p>O <a title="Mauricio Aniche - Blog" href="http://aniche.com.br/blog/" target="_self">Maurício Aniche</a> que participa do DotNetArchitects já se juntou ao projeto pra me ajudar. Já existem alguns códigos publicados no codeplex e uma documentação miníma também. Quem quiser ajudar é mais do que bem vindo! <img src='http://blog.tucaz.net/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </p>
]]></content:encoded>
			<wfw:commentRss>http://blog.tucaz.net/2008/12/28/net-scrum-projeto-open-source/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
	</channel>
</rss>

