IQueryable<T>從IEnumerable<T>中派生,包含了LINQ查詢表達式信息,通過前向轉換為IEnumerable<T>類型的可枚舉集合,允許使用foreach語法循環其中的數據。
LINQToDataTable<T>泛型方法將使用.NET的反射技術從集合中構取DataTable的架構數據,然后循環將集合中的元素添加到DataTable中。
注意:.NET反射定義在System.Reflection命名空間中,該命名空間允許開發人員從現在類型中獲取類型元數據信息 。
LINQToDataTable<T>泛型方法的實現如代碼所示:
//將IEnumerable<T>類型的集合轉換為DataTable類型 public DataTable LINQToDataTable<T>(IEnumerable<T> varlist) { //定義要返回的DataTable對象 DataTable dtReturn = new DataTable(); // 保存列集合的屬性信息數組 PropertyInfo[] oProps = null; if (varlist == null) return dtReturn;//安全性檢查 //循環遍歷集合,使用反射獲取類型的屬性信息 foreach (T rec in varlist) { //使用反射獲取T類型的屬性信息,返回一個PropertyInfo類型的集合 if (oProps == null) { oProps = ((Type)rec.GetType()).GetProperties(); //循環PropertyInfo數組 foreach (PropertyInfo pi in oProps) { Type colType = pi.PropertyType;//得到屬性的類型 //如果屬性為泛型類型 if ((colType.IsGenericType) && (colType.GetGenericTypeDefinition() == typeof(Nullable<>))) { //獲取泛型類型的參數 colType = colType.GetGenericArguments()[0]; } //將類型的屬性名稱與屬性類型作為DataTable的列數據 dtReturn.Columns.Add(new DataColumn(pi.Name, colType)); } } //新建一個用於添加到DataTable中的DataRow對象 DataRow dr = dtReturn.NewRow(); //循環遍歷屬性集合 foreach (PropertyInfo pi in oProps) { //為DataRow中的指定列賦值 dr[pi.Name] = pi.GetValue(rec, null) == null ? DBNull.Value : pi.GetValue(rec, null); } //將具有結果值的DataRow添加到DataTable集合中 dtReturn.Rows.Add(dr); } return dtReturn;//返回DataTable對象 }
---