1. 程式人生 > >將DataSet轉換成List

將DataSet轉換成List

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