none
Preencher IList sem While é possivel ? RRS feed

  • Pergunta

  • Boa noite, estou com uma duvida de performance.

    tenho uma WebApplication que tem algumas classes que são listas.

    Estou preenchendo um IList utilizando um DataReader.

       public IList<Produto> Listar(string tipomovimento, int qtd, string procura, string CLASSECLI, decimal Desconto)
            {
                IList<Produto> produtos = new List<Produto>();
    
                using (DbNetData dbNet = new DbNetData(ConfigurationManager.ConnectionStrings["dbmariterra"].ConnectionString, DataProvider.Odbc))
                {
                    dbNet.Open();
                    QueryCommandConfig Query;
                    Query = new QueryCommandConfig("SET ROWCOUNT 0 select * from web_produto where PD_COD = " + procura.Trim() + "");
                    dbNet.ExecuteQuery(Query);
                    IDataReader reader = dbNet.Reader;
    
                    while (reader.Read())
                    {
                        Produto produto = new Produto();
    
                        if (reader["PD_COD"] != DBNull.Value)
                            produto.Id = (decimal)reader["PD_COD"];
                        if (reader["PD_DES"] != DBNull.Value)
                            produto.Descricao = (string)reader["PD_DES"];
                        if (reader["PD_UNI"] != DBNull.Value)
                            produto.Unidade = (string)reader["PD_UNI"];
                        if (reader["SALDO"] != DBNull.Value)
                            produto.Saldo = (decimal)reader["SALDO"];
    
                        ValorProduto(produto, tipomovimento, produto.Unidade, CLASSECLI, Desconto);
    
                        produtos.Add(produto);
                    }
                }
    
                return produtos;
            }
    
    

    Gostaria de saber se existe alguma outra forma de preencher esse Ilist sem precisar do While, pois a performance está péssima.

    Linguagem Asp.net MVC 3

    BAnco de dados Sybase 5

     

    Desde já agradeço a atenção

     

    segunda-feira, 23 de janeiro de 2012 23:05

Respostas

  • André,

    Veja se este link te ajuda: http://sleom.blogspot.com/2011/02/consuming-idatareader-with-linq.html

    Assim você poderia utilizar uma consulta Linq para retornar uma lista de objetos da classe Produtos.

    Algo como isto:

    IDataReader reader = dbNet.Reader;
    var result = reader.DataRecord(prd => new Produto
    {
        Id = prd.GetInt32(prd.GetOrdinal("PD_COD"),
        Descricao = prd.GetString(prd.GetOrdinal("PD_DESC"),
        Unidade = prd.GetString(prd.GetOrdinal("PD_UNI"),
        Saldo = prd.GetInt32(prd.GetOrdinal("SALDO")
    }).ToList();
    

    Sendo "DataRecord", o extension method criado para a interface IDataReader.

    Abraços!

    • Editado José Eduardo Castro segunda-feira, 23 de janeiro de 2012 23:58
    • Sugerido como Resposta Vitor Mendes terça-feira, 24 de janeiro de 2012 00:47
    • Marcado como Resposta André Faria terça-feira, 24 de janeiro de 2012 11:30
    segunda-feira, 23 de janeiro de 2012 23:57
  • André,

    Você pode atribuir o resultado da consulta em Linq diretamente para a lista que você criou anteriormente. O método "ToList()", ao término da consulta, faz a conversão automática para o tipo de objeto que receberá o resultado.

    Sendo assim, você poderia fazer algo como:

    IList<Produto> produtos = new List<Produto>();
    IDataReader reader = dbNet.Reader;
    
    produtos = reader.DataRecord(prd => new Produto
    {
        Id = prd.GetInt32(prd.GetOrdinal("PD_COD"),
        Descricao = prd.GetString(prd.GetOrdinal("PD_DESC"),
        Unidade = prd.GetString(prd.GetOrdinal("PD_UNI"),
        Saldo = prd.GetInt32(prd.GetOrdinal("SALDO")
    }).ToList();
    
    

    Abraços!

    • Marcado como Resposta André Faria terça-feira, 24 de janeiro de 2012 11:30
    terça-feira, 24 de janeiro de 2012 10:52

Todas as Respostas

  • André,

    Veja se este link te ajuda: http://sleom.blogspot.com/2011/02/consuming-idatareader-with-linq.html

    Assim você poderia utilizar uma consulta Linq para retornar uma lista de objetos da classe Produtos.

    Algo como isto:

    IDataReader reader = dbNet.Reader;
    var result = reader.DataRecord(prd => new Produto
    {
        Id = prd.GetInt32(prd.GetOrdinal("PD_COD"),
        Descricao = prd.GetString(prd.GetOrdinal("PD_DESC"),
        Unidade = prd.GetString(prd.GetOrdinal("PD_UNI"),
        Saldo = prd.GetInt32(prd.GetOrdinal("SALDO")
    }).ToList();
    

    Sendo "DataRecord", o extension method criado para a interface IDataReader.

    Abraços!

    • Editado José Eduardo Castro segunda-feira, 23 de janeiro de 2012 23:58
    • Sugerido como Resposta Vitor Mendes terça-feira, 24 de janeiro de 2012 00:47
    • Marcado como Resposta André Faria terça-feira, 24 de janeiro de 2012 11:30
    segunda-feira, 23 de janeiro de 2012 23:57
  • Nesse caso eu teria que abandonar o IList,e utilizaria sempre o retorno do linq quando for utilizar a coleção de produtos ?

    Ou existe alguma forma de depois o Ilist receber o resultado da funcão ?

    Correto ?

     



    • Editado André Faria terça-feira, 24 de janeiro de 2012 09:49
    terça-feira, 24 de janeiro de 2012 09:46
  • André,

    Você pode atribuir o resultado da consulta em Linq diretamente para a lista que você criou anteriormente. O método "ToList()", ao término da consulta, faz a conversão automática para o tipo de objeto que receberá o resultado.

    Sendo assim, você poderia fazer algo como:

    IList<Produto> produtos = new List<Produto>();
    IDataReader reader = dbNet.Reader;
    
    produtos = reader.DataRecord(prd => new Produto
    {
        Id = prd.GetInt32(prd.GetOrdinal("PD_COD"),
        Descricao = prd.GetString(prd.GetOrdinal("PD_DESC"),
        Unidade = prd.GetString(prd.GetOrdinal("PD_UNI"),
        Saldo = prd.GetInt32(prd.GetOrdinal("SALDO")
    }).ToList();
    
    

    Abraços!

    • Marcado como Resposta André Faria terça-feira, 24 de janeiro de 2012 11:30
    terça-feira, 24 de janeiro de 2012 10:52
  • Muito obrigado.

    Vou fazer hoje mesmo.

    Abraços

    terça-feira, 24 de janeiro de 2012 11:30
  • André,

    Você pode atribuir o resultado da consulta em Linq diretamente para a lista que você criou anteriormente. O método "ToList()", ao término da consulta, faz a conversão automática para o tipo de objeto que receberá o resultado.

    Sendo assim, você poderia fazer algo como:

     

    IList<Produto> produtos = new List<Produto>();
    IDataReader reader = dbNet.Reader;
    
    produtos = reader.DataRecord(prd => new Produto
    {
        Id = prd.GetInt32(prd.GetOrdinal("PD_COD"),
        Descricao = prd.GetString(prd.GetOrdinal("PD_DESC"),
        Unidade = prd.GetString(prd.GetOrdinal("PD_UNI"),
        Saldo = prd.GetInt32(prd.GetOrdinal("SALDO")
    }).ToList();
    
    

    Abraços!

     

    Até aí tudo bem.

    Agora um desafio, realmente ficou bem mais rapido.

    teria como fazer a mesma coisa para um método da seguinte forma:

        public IList<ItemPedido> GetItemsPedido(decimal id, string tipoMovimento, string CLASSECLI, decimal Desconto)
            {
                IList<ItemPedido> items = new List<ItemPedido>();
    
                using (DbNetData dbNet = new DbNetData(ConfigurationManager.ConnectionStrings["dbmariterra"].ConnectionString, DataProvider.Odbc))
                {
                    dbNet.Open();
    
                    QueryCommandConfig Query = new QueryCommandConfig("select * from web_item where WEB_NRPED = "+id.ToString());
                    //Query.Params["WEB_NRPED"] = id;
                    dbNet.ExecuteQuery(Query);
                    IDataReader reader = dbNet.Reader;
                  
    
                    while (reader.Read())
                    {
                        ItemPedido item = new ItemPedido();
    
                        if (reader["WEB_NRPED"] != DBNull.Value)
                            item.Id = (decimal)reader["WEB_NRPED"];
                        if (reader["PD_ITM"] != DBNull.Value)
                        {
                            item.PD_ITM = (decimal)reader["PD_ITM"];
                        }
                        if (reader["PD_COD"] != DBNull.Value)
                        {
                            item.Produto = MariterraSingleton.Instance.MarriterraFacade.GetProduto((decimal)reader["PD_COD"], tipoMovimento, CLASSECLI,Desconto);
                        }
                        if (reader["PD_UNISIGLA"] != DBNull.Value)
                            item.PD_UNISIGLA = (string)reader["PD_UNISIGLA"];
                        if (reader["WEB_QTDE"] != DBNull.Value)
                            item.WEB_QTDE = (decimal)reader["WEB_QTDE"];
                        if (reader["WEB_PRC"] != DBNull.Value)
                            item.WEB_PRC = (decimal)reader["WEB_PRC"];
                        if (reader["WEB_VLRDESC"] != DBNull.Value)
                            item.WEB_VLRDESC = (decimal)reader["WEB_VLRDESC"];
    
                        items.Add(item);
                    }
                }
    
                return items;
            }
    

    sReparem que existe um outro objeto dentro deste que está sendo preenchido atraves de outro método

     item.Produto = MariterraSingleton.Instance.MarriterraFacade.GetProduto((decimal)reader["PD_COD"], tipoMovimento, CLASSECLI,Desconto);<br/><br/>Teria como utilizar essa mesma idéia para preencher essa classe ?
    
    quarta-feira, 25 de janeiro de 2012 21:26