简体   繁体   English

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

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

Code below is me trying to do just that. 下面的代码是我试图做到这一点。 It returns all rows but only like DEFAULT VALUES (0, empty string, empty date...) and "Allow Nulls" is false for all columns in my db table. 它返回所有行,但仅返回默认值(0,空字符串,空日期...),并且对于数据库表中的所有列,“ Allow Nulls”为false。 I am truly stuck. 我真的被困住了。 I am still in process of learning c#, so if someone could please explain to me WHAT am I doing wrong here? 我仍在学习c#,因此如果有人可以向我解释,我在这里做错了什么? Is there a better way to do this? 有一个更好的方法吗?

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

There is a better way ( You need to just do it once and it will help in future). 有一个更好的方法(您只需要执行一次,将来会有所帮助)。 Derive a class from DbDataReader that will take sqldatareader in the constructor: 从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();
    }

So what I have done is passed the SqlDataReader in custom class that can cache the column names with the positions. 因此,我所做的就是在自定义类中传递了SqlDataReader,该类可以缓存具有位置的列名称。 Then you are free to call the Custom implementation using the delegate sqldatareader or write your own functions on top - like I have done for string. 然后,您可以使用委托sqldatareader调用Custom实现,也可以在上面编写自己的函数-就像我对字符串所做的那样。 Little bit of work initially but you can put all checks here like check for DbNull etc and return default values based on that. 最初需要进行一些工作,但是您可以将所有检查放在这里,例如检查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);    
        }

You may need to check the names of the columns coming back so may be store in lower case and then read in lower case. 您可能需要检查返回的列的名称,以便将它们存储为小写,然后以小写读取。 Your code doesnt need to do getordinal anymore and it is much cleaner as well. 您的代码不再需要执行常规操作,并且它也更加干净。

There are several ways to do this using the SqlDataReader and DataTable.... 有几种使用SqlDataReader和DataTable进行此操作的方法。

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

OR 要么

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

OR 要么

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

For simple examples of DataTable take a look at this..... 对于DataTable的简单示例,请看一下这个.....

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

Well it turns out that the code in my first post is OK! 好吧,事实证明,我第一篇文章中的代码还可以! The mistake was in my POCO definition. 错误出在我的POCO定义中。

This is what caused the problem : 这是导致问题的原因:

...

private DateTime _dt_get;    

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


...

Thx for any help... 感谢任何帮助...

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

相关问题 将数据从视图传输到javascript的最佳方式 - Best way to transfer data from view to javascript 从WCF中检索数据表而不使用数据传输对象的最佳方法是什么 - what is the best way to retrieve a datatable from WCF without using Data transfer objects SqlDataReader放入List &lt;&gt;-最快的方法 - SqlDataReader into List<> - Quickest way 将数据合同从服务转移到消费者的最佳方法 - Best way to transfer data contract from service to consumer 将数据从View传输到复杂控件的最佳方法 - Best way to transfer data from View to complex controls 从 SqlDataReader 读取数据 - Read data from SqlDataReader 与SqlDataReader中的数据并行 - Parallelism with Data from SqlDataReader 在SQL Server之间传输数据的最佳方法 - Best way to transfer data between SQL Servers 通过网络在android应用程序和WPF桌面应用程序之间传输数据的最佳方法是什么 - what is the best way to transfer data between android application and WPF desktop application over network 使用 Serilog 记录 SqlCommand CommandText 和参数以及 SqlDataReader 字段的最佳/最短方法是什么? - What's the best/shortest way to log SqlCommand CommandText and Parameters and SqlDataReader fields with Serilog?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM