[英]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.