Performance - Eval

<< Click to Display Table of Contents >>

Navigation:  ASP.NET > Dicas avançadas > Performance >

Performance - Eval

Previous pageReturn to chapter overviewNext page

Introdução

 

É muito comum ver DataBinder.Eval em Repeater, DataGrid e DataList, mas muitos não sabem que ele pode causar problemas de performance.

Vamos ver algumas alternativas ao DataBinder.Eval

 

O Eval é um método que usa Reflection em tempo de execução para descobrir o tipo de dado do DataItem.

E isso pode causar visível lentidão quando o volume de dados é grande, inclusive a própria Microsoft não recomenda o uso dele devido a sobrecarga.

Mas para pequenos volumes de dados vai bem.

 

Explicação

 

Mas o que acontece na prática?

Imagine um Repeater onde seu DataSource é uma tabela com 10 linhas e 5 colunas.

Então você usa Eval para retornar o valor de cada coluna, isso representa 5 chamados a cada linha.

Assim no final das 10 linhas você terá chamando o Eval 50 vezes.

 

Abaixo vou mostrar o uso comum do DataBinder.Eval.

1.O Eval requer 2 ou 3 argumentos.

2.A própria fonte de dados

3.Nome do campo/coluna

4.Formatação

 

Exemplos de uso

 

1-Usando somente o Eval, que não é igual ao DataBinder.Eval.

 

<%# Eval("DataCadastro"%>

 

Resultado: 05/01/2013 14:27:06

 

2-DataBinder.Eval com formatação de dados.

 

<%# DataBinder.Eval(Container.DataItem,"DataCadastro""{0:D}"%>

 

Resultado: quarta-feira, 9 de janeiro de 2013

 

Alternativas ao DataBinder.Eval - Soluções

 

Vou mostrar basicamente 2 alternativas, ambas usando o Container.DataItem, uma no próprio .aspx e outra no .cs (ItemDataBound).

Container.DataItem é onde estão contidos os dados da posição atual da coleção/lista, ou seja, corresponde a uma linha.

A tipagem do DataItem é determinada pelo tipo de DataSource, então se sua fonte de dados é List<String> o DataItem é string.

Para pegar as propriedades de um objeto, você terá que fazer antes a conversão para o respectivo tipo.

Vendo os exemplos vai ficar melhor de entender.

 

Solução 1

 

DataItem - Uso de Container.DataItem com conversão explícita:

 

<%# ((Pessoa)Container.DataItem).DataCadastro %>

 

Container.DataItem com DataSet e DataTable.

 

<%@ Import Namespace="System.Data" %>

...

<asp:Repeater runat="server" ID="Repeater1">

 <ItemTemplate>

         <%#((DataRowView)Container.DataItem)["DataCadastro"]%>

 </ItemTemplate>

</asp:Repeater>  

 

Solução 2

 

Repeater - Mover o Eval para o code behind usando o ItemDataBound

 

Default.aspx

 

<asp:Repeater runat="server" ID="Repeater1" OnItemDataBound="Repeater1_ItemDataBound">

    <ItemTemplate>

        <asp:Literal ID="litDataCadastro" runat="server" />  <!-- REMOVIDO EVAL DAQUI -->

    </ItemTemplate>

</asp:Repeater> 

 

Default.aspx.cs

 

        protected void Repeater1_ItemDataBound(object sender, RepeaterItemEventArgs e)

        {

            if (e.Item.ItemType == ListItemType.AlternatingItem || e.Item.ItemType == ListItemType.Item)

            {

                //Pegar o Container.DataItem e converter para o tipo de dados específico, no meu caso, o tipo é Pessoa.

                Pessoa pessoa = (Pessoa)e.Item.DataItem;

                //Encontrar o Literal no Repeater

                Literal litDataCadastro = (Literal)e.Item.FindControl("litDataCadastro");

                //Popular o literal com a data de cadastro já formatada

                litDataCadastro.Text = pessoa.DataCadastro.ToString("dd/MM/yyyy");

                //Retornará: 05/01/2013

            }

        }

 

 

Solução 3

 

GridView - Mover o Eval para o code behind usando o RowDataBound

 

Default.aspx

 

    <asp:GridView ID="Grid" runat="server" AutoGenerateColumns="False" OnRowDataBound="Grid_RowDataBound">

        <Columns>

            <asp:TemplateField HeaderText="Cidade">

                <ItemTemplate>

                    <asp:HyperLink ID="hlCidade" runat="server" Target="_blank">Cidade</asp:HyperLink>

                </ItemTemplate>

            </asp:TemplateField>

        </Columns>

    </asp:GridView>

 

Default.aspx.cs 

 

        protected void Grid_RowDataBound(object sender, GridViewRowEventArgs e)

        {

            if (e.Row.RowType == DataControlRowType.DataRow)

            {

                DataRowView drv = (DataRowView)e.Row.DataItem;

                string cidade = drv["nm_cidade"].ToString();

                HyperLink hlCidade = (HyperLink)e.Row.FindControl("hlCidade");

                hlCidade.Text = cidade;

                hlCidade.NavigateUrl = "https://maps.google.com/maps?q=" + cidade.ToLower().Replace(' ''+'"&hl=pt-BR&t=v&z=11";

            }

        }

 

Fonte

 

http://cbsa.com.br/post/aspnet---eval-vs-performance.aspx