将数据从SqlDataReader传输到List <someclass>?</someclass>的最佳方法是什么?

时间:2014-06-15 17:09:49

标签: c# collections sqldatareader

下面的代码是我试图做到这一点。它返回所有行,但只返回DEFAULT VALUES(0,空字符串,空日期...),并且对于我的db表中的所有列,“Allow Nulls”为false。我真的被卡住了。我还在学习c#,所以如果有人可以向我解释我在这里做错了什么?有一个更好的方法吗?

   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;
        }

3 个答案:

答案 0 :(得分:1)

有一种更好的方法(你需要做一次,这将有助于将来)。从DbDataReader派生一个类,它将在构造函数中使用sqldatareader:

 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();
    }

所以我所做的就是在自定义类中传递SqlDataReader,该类可以使用位置缓存列名。然后,您可以使用委托sqldatareader自由调用Custom实现,或者在顶部编写您自己的函数 - 就像我为字符串所做的那样。最初的一点工作,但你可以把所有检查放在这里像检查DbNull等,并根据它返回默认值。

 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);    
        }

您可能需要检查返回列的名称,以便以小写形式存储,然后以小写形式阅读。你的代码不再需要做getordinal了,它也更干净。

答案 1 :(得分:1)

有几种方法可以使用SqlDataReader和DataTable ....

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

OR

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

OR

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

对于DataTable的简单示例,请看一下.....

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

答案 2 :(得分:0)

事实证明我的第一篇文章中的代码是开启的!错误在于我的POCO定义。

这就是导致问题的原因:

...

private DateTime _dt_get;    

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


...

任何帮助......