將DataSet轉換成List
阿新 • • 發佈:2019-01-27
App.Config配置檔案
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<connectionStrings>
<add name="GetDataSetConn" connectionString="data source=tong-037;initial catalog=sales;integrated security=true"/>
</connectionStrings>
</configuration>
c#程式碼塊
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Data.SqlClient;
using System.Data;
using System.Reflection;
using System.Configuration;
namespace DatasetConvertList
{
//獲取資料庫連線字串
class GetConnStr
{
public static string ConnStr()
{
string getConn = ConfigurationManager.ConnectionStrings["GetDataSetConn"].ConnectionString;
return getConn;
}
}
//============================將================================================//
//首先定義類,類下面的屬性成員用來接收從table表裡取出的對應欄位
public class UserInfo
{
public int ID { get; set; }
public int Age { get; set; }
public string Nanme { get; set; }
}
class DataTableTolist
{
/// <summary>
/// 獲取List<UserInfo>泛型集合 其實也就是//將DataTable轉化成list<T> where T:class
/// </summary>
/// <param name="connStr">資料庫連線字串</param>
/// <param name="sql">sqL語句</param>
/// <param name="parameter">sql語句的引數</param>
/// <returns>返回一個list</returns>
public IList<UserInfo> GetUserInfoAll( string sql, params SqlParameter[] parameter) //定義一個返回值是list<Userinfo>的方法,
{
using (SqlConnection conn = new SqlConnection(GetConnStr.ConnStr()))
{
conn.Open();
using (SqlCommand cmd = conn.CreateCommand())
{
cmd.CommandText = sql;
foreach (SqlParameter p in parameter)
{
cmd.Parameters.Add(p);
}
IList<UserInfo> list = new List<UserInfo>();//定義一個list 到時候用來存放【已經將table表字段轉換成Userinfo類屬性成員的】類,也就是說list的成員就是Userinfo類的例項,而Userinfo的成員其實就是table表的欄位
//using (SqlDataAdapter dapter=new SqlDataAdapter (cmd))
//{
// dapter.Fill(list);
//}
SqlDataReader dr = cmd.ExecuteReader();
while (dr.Read())
{
UserInfo userinto = new UserInfo(); //例項化一個UserInof類
userinto.ID = (int)dr["id"]; //將table表的id欄位賦值給UserInof類的ID屬性
userinto.Age = (int)dr["age"]; //將table表的age欄位賦值給UserInof類的Age屬性
userinto.Nanme = (string)dr["name"]; //將table表的name欄位賦值給UserInof類的Nanme屬性
list.Add(userinto); //將UserInof類是例項userinfo新增到list中
}
return list; //再把這個list返回去
}
}
}
}
//========================下面是將一個DataSet轉換成一個list=========================//
//首先定義類,類下面的屬性成員用來接收從DataSet裡的Table表裡取出的對應欄位,這也就是一個對映的過程
public class TabName
{
public int ID { get; set; }
public string Name { get; set; }
public int Age { get; set; }
}
class Program
{
/// <summary>
/// 獲取泛型集合,注意,指所有的型別的list哦。【不像上面已經指定了List<T>的型別是UserInfo了哦】
/// </summary>
/// <typeparam name="T">型別</typeparam>
/// <param name="connStr">資料庫連線字串</param>
/// <param name="sql">sql語句</param>
/// <param name="parameter">sql語句的引數</param>
/// <returns>為什麼這個方法的返回值是IList<T>呢?那是因為既然是將DataSet轉換成list所以我就返回一個list</returns>
public List<T> GetList<T>(string sql, params SqlParameter[] parameter)
{
using (SqlConnection conn = new SqlConnection(GetConnStr.ConnStr()))
{
conn.Open();
using (SqlCommand cmd = conn.CreateCommand())
{
cmd.CommandText = sql;
foreach (SqlParameter par in parameter)
{
cmd.Parameters.Add(par);
}
DataSet ds = new DataSet();
//SqlDataAdapter 是 DataSet 和 SQL Server 之間的橋接器,用於檢索和儲存資料,也就是說SqlDataAdapter通過cmd物件執行的sql命令,獲取資料庫中的資料,將獲取到是資料儲存到dapter中,然後用於填充DataSet
using (SqlDataAdapter dapter = new SqlDataAdapter(cmd))
{
//dapter.SelectCommand = cmd;
dapter.Fill(ds);
return DataSetToList<T>(ds, 0);//呼叫下面的DataSetToList方法將DataSet轉換為List
}
}
}
}
/// <summary>
/// DataSetToList
/// </summary>
/// <typeparam name="T">轉換型別</typeparam>
/// <param name="ds">一個DataSet例項,也就是資料來源</param>
/// <param name="tableIndext">DataSet容器裡table的下標,只有用於取得哪個table,也就是需要轉換表的索引</param>
/// <returns></returns>
public List<T> DataSetToList<T>(DataSet ds, int tableIndext)
{
//確認引數有效
if (ds == null || ds.Tables.Count <= 0 || tableIndext < 0)
{
return null;
}
DataTable dt = ds.Tables[tableIndext]; //取得DataSet裡的一個下標為tableIndext的表,然後賦給dt
IList<T> list = new List<T>(); //例項化一個list
// 在這裡寫 獲取T型別的所有公有屬性。 注意這裡僅僅是獲取T型別的公有屬性,不是公有方法,也不是公有欄位,當然也不是私有屬性
PropertyInfo[] tMembersAll = typeof(T).GetProperties();
for (int i = 0; i < dt.Rows.Count; i++)
{
//建立泛型物件。為什麼這裡要建立一個泛型物件呢?是因為目前我不確定泛型的型別。
T t = Activator.CreateInstance<T>();
//獲取t物件型別的所有公有屬性。但是我不建議吧這條語句寫在for迴圈裡,因為沒迴圈一次就要獲取一次,佔用資源,所以建議寫在外面
//PropertyInfo[] tMembersAll = t.GetType().GetProperties();
for (int j = 0; j < dt.Columns.Count; j++)
{
//遍歷tMembersAll
foreach (PropertyInfo tMember in tMembersAll)
{
//取dt表中j列的名字,並把名字轉換成大寫的字母。整條程式碼的意思是:如果列名和屬性名稱相同時賦值
if (dt.Columns[j].ColumnName.ToUpper().Equals(tMember.Name.ToUpper()))
{
//dt.Rows[i][j]表示取dt表裡的第i行的第j列;DBNull是指資料庫中當一個欄位沒有被設定值的時候的值,相當於資料庫中的“空值”。
if (dt.Rows[i][j] != DBNull.Value)
{
//SetValue是指:將指定屬性設定為指定值。 tMember是T泛型物件t的一個公有成員,整條程式碼的意思就是:將dt.Rows[i][j]賦值給t物件的tMember成員,引數詳情請參照http://msdn.microsoft.com/zh-cn/library/3z2t396t(v=vs.100).aspx/html
tMember.SetValue(t, dt.Rows[i][j], null);
}
else
{
tMember.SetValue(t, null, null);
}
break;//注意這裡的break是寫在if語句裡面的,意思就是說如果列名和屬性名稱相同並且已經賦值了,那麼我就跳出foreach迴圈,進行j+1的下次迴圈
}
}
}
list.Add(t);
}
return list.ToList();
}
//我在資料庫裡建了一個T_user表,裡面有三個欄位,自增的ID,age,name
static void Main(string[] args)
{
Program p = new Program();
List<TabName> list = p.GetList<TabName>("select * from T_user where id< [email protected]", new SqlParameter("id", 3));
foreach (var s in list)
{
Console.WriteLine(s.ID);
Console.WriteLine(s.Age);
Console.WriteLine(s.Name);
}
Console.ReadKey();
}
}
}