using System; using System.Collections; using System.Collections.Generic; using System.Text; using System.Data; using System.Reflection; using System.ComponentModel; using System.Diagnostics; namespace XXX.XXX { /// <summary> /// 數據轉換類 /// 說明 :實體,List集合,DataTable相互轉換<br/> /// 作者 :niu<br/> /// 創建時間:2011-05-07<br/> /// 最后修改:2011-07-21<br/> /// </summary> public class DataConvert { #region DataRow轉實體 /// <summary> /// DataRow轉實體 /// </summary> /// <typeparam name="T">數據型類</typeparam> /// <param name="dr">DataRow</param> /// <returns>模式</returns> public static T DataRowToModel<T>(DataRow dr) where T : new() { //T t = (T)Activator.CreateInstance(typeof(T)); T t = new T(); if (dr == null) return default(T); // 獲得此模型的公共屬性 PropertyInfo[] propertys = t.GetType().GetProperties(); DataColumnCollection Columns = dr.Table.Columns; foreach (PropertyInfo p in propertys) { string columnName =((DBColumn) p.GetCustomAttributes(typeof(DBColumn),false)[0]).ColName; // string columnName = p.Name;如果不用屬性,數據庫字段對應model屬性,就用這個 if (Columns.Contains(columnName)) { // 判斷此屬性是否有Setter或columnName值是否為空 object value = dr[columnName]; if (!p.CanWrite || value is DBNull || value == DBNull.Value) continue; try { #region SetValue switch (p.PropertyType.ToString()) { case "System.String": p.SetValue(t, Convert.ToString(value), null); break; case "System.Int32": p.SetValue(t, Convert.ToInt32(value), null); break; case "System.Int64": p.SetValue(t, Convert.ToInt64(value), null); break; case "System.DateTime": p.SetValue(t, Convert.ToDateTime(value), null); break; case "System.Boolean": p.SetValue(t, Convert.ToBoolean(value), null); break; case "System.Double": p.SetValue(t, Convert.ToDouble(value), null); break; case "System.Decimal": p.SetValue(t, Convert.ToDecimal(value), null); break; default: p.SetValue(t, value, null); break; } #endregion } catch(Exception ex) { continue; /*使用 default 關鍵字,此關鍵字對於引用類型會返回空,對於數值類型會返回零。對於結構, * 此關鍵字將返回初始化為零或空的每個結構成員,具體取決於這些結構是值類型還是引用類型*/ } } } return t; } #endregion #region DataTable轉List<T> /// <summary> /// DataTable轉List<T> /// </summary> /// <typeparam name="T">數據項類型</typeparam> /// <param name="dt">DataTable</param> /// <returns>List數據集</returns> public static IList<T> DataTableToList<T>(DataTable dt) where T : new() { IList<T> tList = new List<T>(); if (dt != null && dt.Rows.Count > 0) { foreach (DataRow dr in dt.Rows) { T t = DataRowToModel<T>(dr); tList.Add(t); } } return tList; } #endregion #region DataReader轉實體 /// <summary> /// DataReader轉實體 /// </summary> /// <typeparam name="T">數據類型</typeparam> /// <param name="dr">DataReader</param> /// <returns>實體</returns> public static T DataReaderToModel<T>(IDataReader dr) where T : new() { T t = new T(); if (dr == null) return default(T); using (dr) { if (dr.Read()) { // 獲得此模型的公共屬性 PropertyInfo[] propertys = t.GetType().GetProperties(); List<string> listFieldName = new List<string>(dr.FieldCount); for (int i = 0; i < dr.FieldCount; i++) { listFieldName.Add(dr.GetName(i).ToLower()); } foreach (PropertyInfo p in propertys) { string columnName = p.Name; if (listFieldName.Contains(columnName.ToLower())) { // 判斷此屬性是否有Setter或columnName值是否為空 object value = dr[columnName]; if (!p.CanWrite || value is DBNull || value == DBNull.Value) continue; try { #region SetValue switch (p.PropertyType.ToString()) { case "System.String": p.SetValue(t, Convert.ToString(value), null); break; case "System.Int32": p.SetValue(t, Convert.ToInt32(value), null); break; case "System.DateTime": p.SetValue(t, Convert.ToDateTime(value), null); break; case "System.Boolean": p.SetValue(t, Convert.ToBoolean(value), null); break; case "System.Double": p.SetValue(t, Convert.ToDouble(value), null); break; case "System.Decimal": p.SetValue(t, Convert.ToDecimal(value), null); break; default: p.SetValue(t, value, null); break; } #endregion } catch { //throw (new Exception(ex.Message)); } } } } } return t; } #endregion #region DataReader轉List<T> /// <summary> /// DataReader轉List<T> /// </summary> /// <typeparam name="T">數據類型</typeparam> /// <param name="dr">DataReader</param> /// <returns>List數據集</returns> public static List<T> DataReaderToList<T>(IDataReader dr) where T : new() { List<T> tList = new List<T>(); if (dr == null) return tList; T t1 = new T(); // 獲得此模型的公共屬性 PropertyInfo[] propertys = t1.GetType().GetProperties(); using (dr) { List<string> listFieldName = new List<string>(dr.FieldCount); for (int i = 0; i < dr.FieldCount; i++) { listFieldName.Add(dr.GetName(i).ToLower()); } while (dr.Read()) { T t = new T(); foreach (PropertyInfo p in propertys) { string columnName = p.Name; if (listFieldName.Contains(columnName.ToLower())) { // 判斷此屬性是否有Setter或columnName值是否為空 object value = dr[columnName]; if (!p.CanWrite || value is DBNull || value == DBNull.Value) continue; try { #region SetValue switch (p.PropertyType.ToString()) { case "System.String": p.SetValue(t, Convert.ToString(value), null); break; case "System.Int32": p.SetValue(t, Convert.ToInt32(value), null); break; case "System.DateTime": p.SetValue(t, Convert.ToDateTime(value), null); break; case "System.Boolean": p.SetValue(t, Convert.ToBoolean(value), null); break; case "System.Double": p.SetValue(t, Convert.ToDouble(value), null); break; case "System.Decimal": p.SetValue(t, Convert.ToDecimal(value), null); break; default: p.SetValue(t, value, null); break; } #endregion } catch { //throw (new Exception(ex.Message)); } } } tList.Add(t); } } return tList; } #endregion #region 泛型集合轉DataTable /// <summary> /// 泛型集合轉DataTable /// </summary> /// <typeparam name="T">集合類型</typeparam> /// <param name="entityList">泛型集合</param> /// <returns>DataTable</returns> public static DataTable ListToDataTable<T>(IList<T> entityList) { if (entityList == null) return null; DataTable dt = CreateTable<T>(); Type entityType = typeof(T); //PropertyInfo[] properties = entityType.GetProperties(); PropertyDescriptorCollection properties = TypeDescriptor.GetProperties(entityType); foreach (T item in entityList) { DataRow row = dt.NewRow(); foreach (PropertyDescriptor property in properties) { row[property.Name] = property.GetValue(item); } dt.Rows.Add(row); } return dt; } #endregion #region 創建DataTable的結構 private static DataTable CreateTable<T>() { Type entityType = typeof(T); //PropertyInfo[] properties = entityType.GetProperties(); PropertyDescriptorCollection properties = TypeDescriptor.GetProperties(entityType); //生成DataTable的結構 DataTable dt = new DataTable(); foreach (PropertyDescriptor prop in properties) { dt.Columns.Add(prop.Name); } return dt; } #endregion } }
using System; using System.Collections.Generic; using System.Text; namespace XXX.XXX { /// <summary> /// 數據庫字段對應屬性類 /// 說明 :數據庫字段對應屬性類<br/> /// 作者 :niu<br/> /// 創建時間:2011-07-21<br/> /// 最后修改:2011-07-21<br/> /// </summary> [AttributeUsage(AttributeTargets.Property|AttributeTargets.Method,AllowMultiple=true,Inherited=false)] public class DBColumn : Attribute { private string _colName; /// <summary> /// 數據庫字段 /// </summary> public string ColName { get { return _colName; } set { _colName = value; } } /* AttributeTargets 枚舉 成員名稱 說明 All 可以對任何應用程序元素應用屬性。 Assembly 可以對程序集應用屬性。 Class 可以對類應用屬性。 Constructor 可以對構造函數應用屬性。 Delegate 可以對委托應用屬性。 Enum 可以對枚舉應用屬性。 Event 可以對事件應用屬性。 Field 可以對字段應用屬性。 GenericParameter 可以對泛型參數應用屬性。 Interface 可以對接口應用屬性。 Method 可以對方法應用屬性。 Module 可以對模塊應用屬性。 注意 Module 指的是可移植的可執行文件(.dll 或 .exe),而非 Visual Basic 標准模塊。 Parameter 可以對參數應用屬性。 Property 可以對屬性 (Property) 應用屬性 (Attribute)。 ReturnValue 可以對返回值應用屬性。 Struct 可以對結構應用屬性,即值類型 */ /* 這里會有四種可能的組合: [AttributeUsage(AttributeTargets.Class, AllowMultiple = false, Inherited = false ] [AttributeUsage(AttributeTargets.Class, AllowMultiple = true, Inherited = false ] [AttributeUsage(AttributeTargets.Class, AllowMultiple = false, Inherited = true ] [AttributeUsage(AttributeTargets.Class, AllowMultiple = true, Inherited = true ] 第一種情況: 如果我們查詢Derive類,我們將會發現Help特性並不存在,因為inherited屬性被設置為false。 第二種情況: 和第一種情況相同,因為inherited也被設置為false。 第三種情況: 為了解釋第三種和第四種情況,我們先來給派生類添加點代碼: [Help("BaseClass")] public class Base { } [Help("DeriveClass")] public class Derive : Base { } 現在我們來查詢一下Help特性,我們只能得到派生類的屬性,因為inherited被設置為true,但是AllowMultiple卻被設置為false。因此基類的Help特性被派生類Help特性覆蓋了。 第四種情況: 在這里,我們將會發現派生類既有基類的Help特性,也有自己的Help特性,因為AllowMultiple被設置為true。 */ } }