1. 程式人生 > >用Linq和Dataview篩選查詢DataTable資料,DataTable和List相互轉換

用Linq和Dataview篩選查詢DataTable資料,DataTable和List相互轉換

DataTable 的篩選如果直接用select方法返回的是DataRow[]陣列,不適合我們再次利用DataTable,

利用DataView可以通過如下方式實現查詢結果直接為DataTable:

                DataTable dt = connection.GetOleDbSchemaTable(OleDbSchemaGuid.Primary_Keys, new object[] { null, null });
                DataView view = new DataView();
                view.Table = dt;
                view.RowFilter = string.Format("table_name='{0}'", tableName);
                return view.ToTable();

引用System.Data.DataExtenstion名稱空間:

var result=from r in dt.AsEnumable() where r.Field<bool>(“checked”)==true select r;

可以對DataTable的列進行隱藏:

ds.Tables[ "stdinfo "].Columns[ "備註 "].ColumnMapping   =   MappingType.Hidden; 
解決..上面這句語句實現了隱藏[ "備註 "]列的功能.

DataTable可以返回物件列表List,通過linq來實現:

            List<ColumnInfo> result = new List<ColumnInfo>();
            DataTable dt=DBHelperOleDb.GetColumnInfo(tableName);
            var a = (from row in dt.AsEnumerable()
                    where 1 == 1
                    select new
                    {
                        ColumnName = row.Field<string>("COLUMN_NAME"),
                        ColumnOrder = row.Field<string>("CORDINAL_pOSITION"),
                        DefaultVal = row.Field<string>("COLUMN_DEFAULT"),
                        Description = row.Field<string>("DESCRIPTION"),
                        IsIdentity = row.Field<string>("Column_FLAGS"),//
                        IsPrimaryKey = row.Field<string>("Column_FLAGS"),//
                        Length = row.Field<string>("CHARACTER_MAXIMUM_LENGTH"),
                        Nullable = row.Field<string>("IS_NULLABLE"),
                        Precision = row.Field<string>("NUMERIC_PRECISION"),
                        Scale = row.Field<string>("NUMERIC_SCALE"),
                        TypeName = row.Field<string>("DATA_TYPE")
                    }).ToList();

引用名稱空間:System.Data.DataSetExtension:

var reslult=from r in dt.AsEnumable() where r.Field<bool>("check")==true select r;

DataTable資料轉換到集合類:
        /// DataTable 轉換為List 集合
        /// </summary>
        /// <typeparam name="TResult">型別</typeparam>
        /// <param name="dt">DataTable</param>
        /// <returns></returns>
        //<型別引數必須是類並且具有無引數的公共建構函式。當與其他約束一起使用時,new()約束必須最後指定。<
        public static List<TResult> ToList<TResult>(this DataTable dt) where TResult : class,new()
        {


            //建立一個屬性的列表
            List<PropertyInfo> prlist = new List<PropertyInfo>();
            //獲取TResult的型別例項  反射的入口
            Type t = typeof(TResult);
            //獲得TResult 的所有的Public 屬性 並找出TResult屬性和DataTable的列名稱相同的屬性(PropertyInfo) 並加入到屬性列表
            Array.ForEach<PropertyInfo>(t.GetProperties(), p => { if (dt.Columns.IndexOf(p.Name) != -1) prlist.Add(p); });
            //建立返回的集合
            List<TResult> oblist = new List<TResult>();
            foreach (DataRow row in dt.Rows)
            {
                //建立TResult的例項
                TResult ob = new TResult();
                //找到對應的資料,並賦值
                prlist.ForEach(p => { if (row[p.Name] != DBNull.Value) p.SetValue(ob, row[p.Name], null); });
                //放入到返回的集合中.
                oblist.Add(ob);
            }
            return oblist;
        }

List也可以轉換成DataTable:
    /// 將泛型別集合List類轉換成DataTable 
        /// </summary> 
        /// <param name="list">泛型別集合</param> 
        /// <returns></returns> 
        public static DataTable ToDataTable<T>(List<T> entitys)
        {

            //檢查實體集合不能為空 
            if (entitys == null || entitys.Count < 1)
            {
                throw new Exception("需轉換的集合為空");
            }

            //取出第一個實體的所有Propertie 
            Type entityType = entitys[0].GetType();
            PropertyInfo[] entityProperties = entityType.GetProperties();

            //生成DataTable的structure 
            //生產程式碼中,應將生成的DataTable結構Cache起來,此處略 
            DataTable dt = new DataTable();
            for (int i = 0; i < entityProperties.Length; i++)
            {
                //dt.Columns.Add(entityProperties[i].Name, entityProperties[i].PropertyType);
                dt.Columns.Add(entityProperties[i].Name);
            }

            //將所有entity新增到DataTable中 
            foreach (object entity in entitys)
            {
                //檢查所有的的實體都為同一型別 
                if (entity.GetType() != entityType)
                {
                    throw new Exception("要轉換的集合元素型別不一致");
                }
                object[] entityValues = new object[entityProperties.Length];
                for (int i = 0; i < entityProperties.Length; i++)
                {
                    entityValues[i] = entityProperties[i].GetValue(entity, null);

                }
                dt.Rows.Add(entityValues);
            }
            return dt;
        } 

datatable和list的轉化:

現在的DataTable慢慢退出歷史舞臺,主要是有以下幾個原因:


1.List<t>是強型別化的,而DataTable不是一般的DataTable,
訪問某列時,是通過string的ColumnName來取得的,
比如:string name = dt.Rows[i][&quot;Name&quot;].ToString();
因為是string的列名,存在記錯寫錯的風險,且編譯不檢查而List<t>,
因為型別化的元素,程式設計時屬性可以有IDE的智慧感知來選擇,編碼更方便。
不容易出錯:string name = list[0].Name;


2.Linq的強有力支援,使得操作List<t>有前所未有的快感其實在linq出來之前,
還是DataTable用的多,因為要想過濾資料,可以用DataView,DataTable.Select()等方法。
而List<t>只能是自己寫迴圈,麻煩。Linq出來之後,where,join,group by,order by...等等操作,
對於List<t>的查詢真是很便利。


3.DataTable的結構遠比List<t>要複雜,記憶體佔用量更大。在有變化的場合下,
DataTable裡要維護不同RowState的資料(修改前的和現在的),還有Schema資料List<t>就沒有這些累贅,更輕快。所以,Linq+List<t>才使得現在大家越來越傾向使用List<t>而不是DataTable

                                                                              -------------以上評價來自網路