none
IDataReader RRS feed

  • Pergunta

  • Pessoal, preciso da ajuda de vcs.

    Gostaria de saber se tem algo errado com este código ou possa ocorrer erros futuramente?

    Na minha camada Dal tenho o seguinte método:

    public ClienteDto[] LoadAll()
    {
    List<ClienteDto> clientes = new List<ClienteDto>();

    try
    {
    string sql = "SELECT * FROM TB_CLIENTES";
    IDataReader dr = Database.MsAccessDB.ExecuteReader(sql);

    while (dr.Read())
    {
    ClienteDto c = new ClienteDto();
    c.ID = (int)dr["CLIENTE_ID"];
    c.Nome = dr["NOME"].ToString();
    clientes.Add(c);
    }

    dr.Close();
    dr.Dispose();

    }
    catch ( Exception e)
    {
    System.Diagnostics.Debug.Fail(e.Message);
    }

    return clientes.ToArray();
    }

    E tambem possuo uma classe Helper para acesso ao Database


    public static IDataReader ExecuteReader(string sql)
    {
    this.OpenDB();

    IDbCommand command = this.mConnection.CreateCommand();
    command.CommandText = sql;

    System.Data.IDataReader dr = comando.ExecuteReader(CommandBehavior.CloseConnection);

    return dr;
    }



    Esse código poderá apresentar problemas?

    Abraços


    terça-feira, 21 de outubro de 2008 01:46

Todas as Respostas

  • Ninguem?????????????
    terça-feira, 21 de outubro de 2008 17:31
  • Pessoal, ninguem pode avaliar o codigo pra mim??????????
    sexta-feira, 24 de outubro de 2008 12:33
  • Hernani,

     

    Não testei mas só olhando não estou vendo nenhum problema. Você já compilou esse código ?

     

    Ari

    sábado, 25 de outubro de 2008 00:16
  • Olá Hernani,

     

    À primeira vista, vejo muitas coisas que você poderia melhorar nesse seu código para evitar problemas de funcionamento, performance, e escalabilidade, no futuro... Entre eles:

     

    1-) Você não está tratando as exceções corretamente

    Se alguma exceção ocorrer quando este código estiver sendo executado em produção, ela será ocultada e sua aplicação irá apresentar resultados inesperados...

     

    Se você não consegue / sabe tratar uma exceção no método atual, deve sempre reencaminhar a exceção para o método que fez a chamada, para que este possa tratar o erro, se conseguir:

     

    Code Snippet

     

     try

     {

    // ...

     }

     catch (Exception e)

     {

    System.Diagnostics.Debug.Fail(e.Message);

    throw e;

     }

     

     

     

    2-) Você não garante que o DataReader seja fechado se ocorrer uma exceção

    O seu DataReader só está sendo fechado se nenhuma Exception ocorrer... Uma vez que o seu código já utiliza um bloco Try...Catch, você deveria implementar o bloco Finally, e neste bloco fechar/liberar o DataReader. Como você deve saber, o bloco Finally é executado sempre, independente se ocorreram ou não, Exceptions no meio do caminho...

     

    Code Snippet

     

     IDataReader dr = null;

     

     try

     {

    // ...

     }

     catch (Exception e)

     {

    // ...

     }

     finally

     {

    if (dr != null)

    {

    dr.Dispose();

    }

     }

     

     

     

    3-) Você está retornando um tipo pouco flexível (array)

    Ao invés de retornar um array da classe ClienteDto, você poderia retornar um IEnumerable<> ou, melhor ainda, IList<>, muito mais flexível que o array, e que permitiria que outras camadas pudessem manipular a coleção mais facilmente (Ex.: adicionar itens, remover itens, etc...).

     

    Code Snippet

     

     public IList<ClienteDto> LoadAll()

     {

    List<ClienteDto> clientes = new List<ClienteDto>();

    // ...

     

    return clientes;

     }

     

     

     

    4-) Você está selecionando TODOS os campos da tabela, sempre

    Utilizar SELECT * FROM Tabela não é uma boa prática. Você deve selecionar apenas os campos que você realmente precisa. Mesmo que durante o desenvolvimento você perceba que precisa de todos, deve, mesmo assim, definir explicitamente cada um dos campos que deseja selecionar, para que no futuro, quando adicionar mais campos, estes não sejam trazidos sem necessidade.

     

    Code Snippet

     

     string sql = "SELECT Cliente_ID, Nome FROM TB_CLIENTES";

     

     

     

    5-) Você utiliza o nome do campo ao ler o campo do DataReader, dentro de um loop

    Ao ler o valor de um campo de um campo no DataReader, como você sabe, você pode informar o nome do campo, ou ainda o índice numérico desse campo. Obter o valor via índice é muito mais rápido que via nome do campo, já que internamente o DataReader terá de descobrir qual é o índice correspondente ao nome do campo que você está informando... Essa diferença de performance é bem pequena quando você faz a leitura de meia dúzia de registros, mas quando a quantidade de registros começa a crescer, a diferença de performance vai aumentando cada vez mais também. Assim, para garantir uma melhor performance, você poderia obter o índice dos campos antes de começar a leitura, e utilizá-los para obter os valores dos campos, mais rapidamente:

     

    Code Snippet

     

     // Obtém o índice dos campos

     int posicaoId = dr.GetOrdinal("Cliente_Id");

     int posicaoNome = dr.GetOrdinal("Nome");

     

     while (dr.Read())

     {

    ClienteDto c = new ClienteDto();

     

    c.ID = (int)dr[posicaoId];

    c.Nome = dr[posicaoNome].ToString();

     

    clientes.Add(c);

     }

     

     

     

    Existem ainda outros pontos que poderiam ser melhorados, mas esses acima são os mais importantes (minha opinião).

     

    Abraços,
    Caio Proiete




    Caio Proiete
    http://www.caioproiete.com
    sábado, 25 de outubro de 2008 00:51
    Moderador