none
Classes e stored procedures RRS feed

  • Pergunta

  • Pessoal,

    Vamos supor que eu tenha uma classe que possua 15 propriedades.
    Entao tenho uma stored procedure que retorna esses 15 propriedades e popula a classe.
    FUNCIONA PERFEITAMENTE

    Agora supondo que eu va chamar uma outra stored procedure e esta so me retorna os campos nome e email.
    Quando ela vai popular a classe, isso gera uma excessao, pois a stored procedure nao esta retornando todas as outras propriedades.
    Acontece que muitas vezes, eu nao preciso de todos os dados para realizar um processo.

    Como fazer com que mesmo retornando alguns dados, a classe nao gere excessao ?

    Abracos

    quarta-feira, 31 de outubro de 2012 04:36

Todas as Respostas

  • Como você esta instanciando sua Classe?

    um exemplo que você pode usar:

    Pessoa pessoa = new Pessoa() { Nome = "Nome da Pessoa", Email = "Email@email.com" };

    quarta-feira, 31 de outubro de 2012 10:14
  • Como o Pedro falou, depende de como você está fazendo.

    A sua excessão é gerada em que momento? No construtor da classe?

    Está usando ado.net ou ORM?


    Sou só uma little padawan que tem sorte de andar com jedis, mas farei o possível por quem precisar :)

    Se precisar: @MayogaX

    quarta-feira, 31 de outubro de 2012 11:35
  • Além das dicas já dadas pelos colegas, você tem que avaliar como os dados são persistidos, pois uma vez que você resolva a questão da exceção, sua classe não estará com todos os dados necessários para passar para sua SP, logo, informações podem ser perdidas, acredito que tenha que criar métodos (e sp's) específicas para persistir as informações isoladas, caso começe a utilizar destes recursos (carregar partes).

    quarta-feira, 31 de outubro de 2012 12:26
  • Mas é essa a questao:

    Se eu quero retornar todos os dados da tabela, eu populo a classe inteira.
    Mas e se eu so quiser trazer da mesma tabela apenas 2 campos, terei que fazer uma outra classe pra receber somente 2 campos ?

    Nao posso usar a classe existente ?

    quinta-feira, 1 de novembro de 2012 17:25
  • Como você esta instanciando sua classe, poste seu código que fica mais facil de ajudar, uma forma de instanciar só dois campos de todos é fazendo assim

    Pessoa pessoa = new Pessoa() { Nome = "Nome da Pessoa", Email = "Email@email.com" };


    quinta-feira, 1 de novembro de 2012 19:56
  • Como você está populando os dados?

    utilizando o DBDataReader Tipo base.

    uma forma viável.

    Public Class Pessoa
    {
    public int id;
    public string Nome;
    }
    
    
    public void Funcao()
    {
    
    List<Pessoa> lst_Pessoa = new List<Pessoa>();
    
    cmd...
    SqlDataReader rd = new cmd.ExecuteReader();
    while(rd.Read())
    {
        lst_Pessoa.Add(
            new Pessoa
            {
                 Nome = rd["Nome"].ToString();
            }
        );
    }   
    
    }



    Se a resposta foi útil por favor qualifique. Italo Biguzi Duarte, Desenvolvedor ASP.NET C#, Italo.biguzzi@gmail.com

    sexta-feira, 2 de novembro de 2012 13:08
  • Neto,

    Você pode criar um extension method ou um método mesmo, para validar se este retorno possui a devida coluna para preenche a propriedade e logo em seguida validar se esta coluna tem o valor.

    Não existe necessidade de criar uma classe para representar cada retorno de um select ou procedure, veja:

    using System;
    using System.Collections.Generic;
    using System.Data;
    using System.Data.SqlClient;
    
    namespace ConsoleApplication1
    {
    
        public class Customers
        {
            public string Country { get; set; }
            public string Phone { get; set; }
        }
    
        class Program
        {
            static void Main(string[] args)
            {
                using (SqlConnection con = new SqlConnection(@"Data Source=.\SQL2012;Initial Catalog=Northwind;User ID=sa;Password=sa"))
                using (SqlCommand cmd = new SqlCommand(@"SELECT TOP 10
                                                        --[Phone],
                                                          [Country]
                                                        FROM [Northwind].[dbo].[Customers]", con))
                {
                    List<Customers> lista = new List<Customers>();
    
                    con.Open();
                    SqlDataReader da = cmd.ExecuteReader();
    
                    while (da.Read())
                    {
                        Customers c = new Customers();
    
                        if (da.HasColumn("Country") && da["Country"] != DBNull.Value)
                            c.Country = da["Country"].ToString();
    
                        if (da.HasColumn("Phone") && da["Phone"] != DBNull.Value)
                            c.Country = da["Phone"].ToString();
    
                        lista.Add(c);
                    }
                }
            }
        }
    
        public static class ExtensionsHelper
        {
            public static bool HasColumn(this IDataRecord dr, string columnName)
            {
                for (int i = 0; i < dr.FieldCount; i++)
                {
                    if (dr.GetName(i).Equals(columnName, StringComparison.InvariantCultureIgnoreCase))
                        return true;
                }
                return false;
            }
        }
    }
    

    No exemplo acima só teremos objetos com a propriedade "Country" preenchida, pois a outra propriedade não foi retornada na consulta.

    Veja este thread do site stackoverflow para mais sugestões:
    http://stackoverflow.com/questions/373230/check-for-column-name-in-a-sqldatareader-object

    Vitor Mendes | Seu feedback é muito importante para todos!
    Visite o meu site: http://www.vitormendes.com.br/

    sexta-feira, 2 de novembro de 2012 14:27