繁体   English   中英

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

[英]What is the best way to transfer data from SqlDataReader into List<SomeClass>?

下面的代码是我试图做到这一点。 它返回所有行,但仅返回默认值(0,空字符串,空日期...),并且对于数据库表中的所有列,“ 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;
        }

有一个更好的方法(您只需要执行一次,将来会有所帮助)。 从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);    
        }

您可能需要检查返回的列的名称,以便将它们存储为小写,然后以小写读取。 您的代码不再需要执行常规操作,并且它也更加干净。

有几种使用SqlDataReader和DataTable进行此操作的方法。

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

要么

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

要么

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

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

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

好吧,事实证明,我第一篇文章中的代码还可以! 错误出在我的POCO定义中。

这是导致问题的原因:

...

private DateTime _dt_get;    

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


...

感谢任何帮助...

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM