2014-06-15 2 views
1

Le code ci-dessous est moi essayant de faire juste cela. Il retourne toutes les lignes mais seulement comme DEFAULT VALUES (0, chaîne vide, date vide ...) et "Allow Nulls" est faux pour toutes les colonnes de ma table db. Je suis vraiment coincé. Je suis encore en train d'apprendre C#, donc si quelqu'un pourrait m'expliquer, qu'est-ce que je fais mal ici? Y a-t-il une meilleure manière de faire cela?Quel est le meilleur moyen de transférer des données de SqlDataReader dans la liste <SomeClass>?

public List<XNarudzbe> GetXNarudzbe() 
     { 
      var listXnar = new List<XNarudzbe>(); 

      using (SqlConnection NConnection = new SqlConnection(Params.ConnectionStr)) 
      { 
       NConnection.Open(); 
       using (var cmd = new SqlCommand("SELECT * FROM [dbo].[XDATA_NARUDZBE]", NConnection)) 
       { 
        SqlDataReader reader = cmd.ExecuteReader(); 

        int id = reader.GetOrdinal("ID"); 
        int dt_get = reader.GetOrdinal("DT_GET"); 
        int rn_datum = reader.GetOrdinal("RN_DATUM"); 
        int datum = reader.GetOrdinal("DATUM"); 
        int dt_stamp = reader.GetOrdinal("DT_STAMP"); 
        int art_id = reader.GetOrdinal("ART_ID"); 
        int cijena_k = reader.GetOrdinal("CIJENA_K"); 
        int cijena_mp = reader.GetOrdinal("CIJENA_MP"); 
        int cijena_vp = reader.GetOrdinal("CIJENA_VP"); 
        int faktura = reader.GetOrdinal("FAKTURA"); 
        int isporuceno = reader.GetOrdinal("ISPORUCENO"); 
        int iznos_k = reader.GetOrdinal("IZNOS_K"); 
        int iznos_p = reader.GetOrdinal("IZNOS_P"); 
        int naruceno = reader.GetOrdinal("NARUCENO"); 
        int narudzba = reader.GetOrdinal("NARUDZBA"); 
        int otpremnica = reader.GetOrdinal("OTPREMNICA"); 
        int pdv = reader.GetOrdinal("PDV"); 
        int povrat_k = reader.GetOrdinal("POVRAT_K"); 
        int povrat_p = reader.GetOrdinal("POVRAT_P"); 
        int pp_id = reader.GetOrdinal("PP_ID"); 
        int preporuka = reader.GetOrdinal("PREPORUKA"); 
        int rabat = reader.GetOrdinal("RABAT"); 
        int rn_id = reader.GetOrdinal("RN_ID"); 
        int skart = reader.GetOrdinal("SKART"); 
        int user_id = reader.GetOrdinal("USER_ID"); 
        int var_n = reader.GetOrdinal("VAR_N"); 
        int var_v = reader.GetOrdinal("VAR_V"); 
        int veleprodaja = reader.GetOrdinal("VELEPRODAJA"); 
        int vraceno = reader.GetOrdinal("VRACENO"); 
        int isporuka_id = reader.GetOrdinal("ISPORUKA_ID"); 
        int otpremljeno = reader.GetOrdinal("OTPREMLJENO"); 
        int promjena = reader.GetOrdinal("PROMJENA"); 
        int rj_id = reader.GetOrdinal("RJ_ID"); 
        int zakljucano = reader.GetOrdinal("ZAKLJUCANO"); 

        if (reader.HasRows) 
        { 
         while (reader.Read()) 
         { 

          var recXNar = new XNarudzbe(); 

          recXNar.id = reader["ID"] as decimal? ?? 0M; // reader.GetDecimal(id); 
          recXNar.dt_get = reader.GetDateTime(dt_get); 
          recXNar.rn_datum = reader.GetDateTime(rn_datum); 
          recXNar.datum = reader.GetDateTime(datum); 
          recXNar.dt_stamp = reader.GetDateTime(dt_stamp); 
          recXNar.art_id = reader.GetDecimal(art_id); 
          recXNar.cijena_k = reader.GetDecimal(cijena_k); 
          recXNar.cijena_mp = reader.GetDecimal(cijena_mp); 
          recXNar.cijena_vp = reader.GetDecimal(cijena_vp); 
          recXNar.faktura = reader.GetDecimal(faktura); 
          recXNar.isporuceno = reader.GetDecimal(isporuceno); 
          recXNar.iznos_k = reader.GetDecimal(iznos_k); 
          recXNar.iznos_p = reader.GetDecimal(iznos_p); 
          recXNar.naruceno = reader.GetDecimal(naruceno); 
          recXNar.narudzba = reader.GetDecimal(narudzba); 
          recXNar.otpremnica = reader.GetDecimal(otpremnica); 
          recXNar.pdv = reader.GetDecimal(pdv); 
          recXNar.povrat_k = reader.GetDecimal(povrat_k); 
          recXNar.povrat_p = reader.GetDecimal(povrat_p); 
          recXNar.pp_id = reader.GetDecimal(pp_id); 
          recXNar.preporuka = reader.GetDecimal(preporuka); 
          recXNar.rabat = reader.GetDecimal(rabat); 
          recXNar.rn_id = reader.GetDecimal(rn_id); 
          recXNar.skart = reader.GetDecimal(skart); 
          recXNar.user_id = reader.GetDecimal(user_id); 
          recXNar.var_n = reader.GetDecimal(var_n); 
          recXNar.var_v = reader.GetDecimal(var_v); 
          recXNar.veleprodaja = reader.GetDecimal(veleprodaja); 
          recXNar.vraceno = reader.GetDecimal(vraceno); 
          recXNar.isporuka_id = reader.GetString(isporuka_id); 
          recXNar.otpremljeno = reader.GetString(otpremljeno); 
          recXNar.promjena = reader.GetString(promjena); 
          recXNar.rj_id = reader.GetString(rj_id); 
          recXNar.zakljucano = reader.GetString(zakljucano); 

          listXnar.Add(recXNar); 

         } 
        } 

        reader.Close(); 
       } 

      } 
      return listXnar; 
     } 
+0

Je ne sais pas si elle est plus vite, mais pourrait essayer passer les valeurs dans un cteur. – Paparazzi

Répondre

1

Il y a une meilleure façon (vous devez juste le faire une fois et cela aidera à l'avenir). Dérivez une classe de DbDataReader qui prendra sqldatareader dans le constructeur:

public class CustomReader : DbDataReader 
{ 
    private readonly SqlDataReader sqlDataReader; 
    //Set the sqlDataReader 
    public CustomReader(SqlDataReader sqlDataReader) 
    { 
     this.sqlDataReader = sqlDataReader; 
     //Cache the names 
     this.CacheColumns(); 
    } 
    private Dictionary<string,int> nameOrdinals = new Dictionary<string, int>(); 
    private void CacheColumns() 
    { 
     int fieldCount= this.sqlDataReader.FieldCount; 
     for (int i = 0; i <= fieldCount-1; i++) 
     { 
      string name=sqlDataReader.GetName(i); 
      nameOrdinals.Add(name,i); 
     } 
    } 

    public override object this[string name] 
    { 
     get 
     { 
      int ordinal=this.nameOrdinals[name]; 
      return this.GetValue(ordinal); 
     } 
    } 
    //Custom implementation 
    public string GetString(string name) 
    { 
     int ordinal = this.nameOrdinals[name]; 
     return this.GetString(ordinal); 
    } 
    //Custom implementation 
    public string GetString(string name,string defaultValue) 
    { 
     int ordinal = this.nameOrdinals[name]; 
     if (this.IsDBNull(ordinal)) 
     { 
      return defaultValue; 
     } 

     return this.GetString(ordinal); 
    } 

    //return from sqlDataReader 
    public override string GetString(int ordinal) 
    { 
     return sqlDataReader.GetString(ordinal); 
    } 


    public override void Close() 
    { 
     sqlDataReader.Close(); 
    } 

Alors ce que je l'ai fait est passé SqlDataReader dans la classe personnalisée qui peut mettre en cache les noms de colonnes avec les positions. Ensuite, vous êtes libre d'appeler l'implémentation personnalisée en utilisant le délégué sqldatareader ou d'écrire vos propres fonctions en haut - comme je l'ai fait pour la chaîne. Peu de travail au départ, mais vous pouvez mettre tous les contrôles ici comme vérifier DbNull etc et retourner les valeurs par défaut basées sur cela.

SqlCommand sqlCommand = new SqlCommand("select * from cats",sqlConnection); 
     SqlDataReader reader = sqlCommand.ExecuteReader(); 
     CustomReader customReader = new CustomReader(reader); 
     List<Cat> list = new List<Cat>(); 
     while (customReader.Read()) 
     { 
      Cat cat = new Cat(); 
      cat.Id = customReader.GetString("id"); 
      cat.Name = customReader.GetString("name"); 
      list.Add(cat);  
     } 

Vous devrez peut-être vérifier les noms des colonnes qui reviennent, vous pouvez donc les stocker en minuscules et les lire ensuite en minuscules. Votre code n'a plus besoin de faire getordinal et il est aussi beaucoup plus propre.

+0

C'est une façon plus agréable, merci de l'essayer dans un projet plus important! Pouvez-vous me dire où j'ai mal fait? Je reçois toutes les lignes uniquement avec les valeurs par défaut. Comme je l'ai dit, la table db n'a pas de champs nullables (environ 70000 lignes) donc ce n'est pas à propos de DBNull ... ??? – EmirZ

+0

vous n'avez pas besoin de faire reader.hasrows, reader.read() est un booléen et qui peut être à l'origine. Alors, ramassez les hasards d'en haut et essayez. Pensez qu'il n'est peut-être même pas en train de lire les données du lecteur. – Avneesh

0

Eh bien, il se trouve que le code dans mon premier message est OK! L'erreur était dans ma définition de POCO.

C'est ce qui a causé le problème:

... 

private DateTime _dt_get;  

public DateTime dt_get 
{ 
    get { return _dt_get; } 
    set { value = _dt_get; } // <-- !!! insted of set { _dt_get = value; } 
} 


... 

Thx pour toute aide ...

+1

Vous savez que vous pouvez utiliser des propriétés implémentées automatiquement, n'est-ce pas? par exemple. 'public DateTime dt_get {get; ensemble;} '. –

1

Il y a plusieurs façons de le faire en utilisant le SqlDataReader et DataTable ....

 IEnumerable<DataRow> list0 = dt.AsEnumerable(); 

OU

 List<DataRow> list1 = new List<DataRow>(dt.Select()); 

OU

 List<DataRow> list2 = dt.AsEnumerable().ToList(); 

Pour des exemples simples de DataTable jeter un oeil à cette .....

http://www.nakdev.somee.com/#2&2AD97ECBE2AE41D08191F6E4C773D8A9&cs

Questions connexes