标签:
在C#中通过反射机制将查询到的DataTable或DataReader转换成相对应的对象类型。
1 /// <summary> 2 /// 反射操作工具类 3 /// </summary> 4 public class ReflectionUtil 5 { 6 #region 根据反射机制将dataTable中指定行的数据赋给obj对象 7 8 /// <summary> 9 /// 根据反射机制将dataTable中指定行的数据赋给obj对象 10 /// </summary> 11 /// <param name="obj">obj对象</param> 12 /// <param name="dataTable">dataTable</param> 13 /// <param name="rowIndex">指定行</param> 14 public static void ConvertDataRowToModel(object obj, DataTable dataTable, int rowIndex) 15 { 16 //指定行不存在 17 if (dataTable.Rows.Count < (rowIndex + 1)) 18 throw new Exception("指定行不存在!"); 19 20 //DataTable列为空! 21 if (dataTable.Columns.Count < 1) 22 throw new Exception("DataTable列为空!"); 23 24 Type type = obj.GetType(); 25 PropertyInfo[] pInfos = type.GetProperties(); 26 27 try 28 { 29 for (int i = 0; i < dataTable.Columns.Count; i++) 30 { 31 for (int j = 0; j < pInfos.Length; j++) 32 { 33 //全部转换为小写的作用是防止数据库列名的大小写和属性的大小写不一致 34 if (dataTable.Columns[i].ColumnName.ToLower() == pInfos[j].Name.ToLower()) 35 { 36 PropertyInfo pInfo = type.GetProperty(pInfos[j].Name); //obj某一属性对象 37 object colValue = dataTable.Rows[rowIndex][i]; //DataTable 列值 38 SetObjectValue(obj, colValue, pInfo, pInfos, j); 39 break; 40 } 41 } 42 } 43 } 44 catch (Exception ex) 45 { 46 //LogTxt.LogException(ex.Message + "\r\n" + ex.Source + "\r\n" + ex.TargetSite + "\r\n" + ex.StackTrace + "\r\n"); 47 throw ex; 48 } 49 } 50 51 #endregion 52 53 #region 将值赋给object属性 54 55 public static void SetObjectValue(object obj, object colValue, PropertyInfo pInfo, PropertyInfo[] pInfos, int j) 56 { 57 if (!ObjectIsNull(colValue)) 58 { 59 if (pInfos[j].PropertyType.FullName == "System.String") 60 { 61 pInfo.SetValue(obj, Convert.ToString(colValue), null); 62 } 63 else if (pInfos[j].PropertyType.FullName == "System.Int32") 64 { 65 pInfo.SetValue(obj, Convert.ToInt32(colValue), null); 66 } 67 else if (pInfos[j].PropertyType.FullName == "System.Int64") 68 { 69 pInfo.SetValue(obj, Convert.ToInt64(colValue), null); 70 } 71 else if (pInfos[j].PropertyType.FullName == "System.Single") 72 { 73 pInfo.SetValue(obj, Convert.ToSingle(colValue), null); 74 } 75 else if (pInfos[j].PropertyType.FullName == "System.Double") 76 { 77 pInfo.SetValue(obj, Convert.ToDouble(colValue), null); 78 } 79 else if (pInfos[j].PropertyType.FullName == "System.Decimal") 80 { 81 pInfo.SetValue(obj, Convert.ToDecimal(colValue), null); 82 } 83 else if (pInfos[j].PropertyType.FullName == "System.Char") 84 { 85 pInfo.SetValue(obj, Convert.ToChar(colValue), null); 86 } 87 else if (pInfos[j].PropertyType.FullName == "System.Boolean") 88 { 89 pInfo.SetValue(obj, Convert.ToBoolean(colValue), null); 90 } 91 else if (pInfos[j].PropertyType.FullName == "System.DateTime") 92 { 93 pInfo.SetValue(obj, Convert.ToDateTime(colValue), null); 94 } 95 //可空类型 96 else if (pInfos[j].PropertyType.FullName == "System.Nullable`1[[System.DateTime, mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089]]") 97 { 98 pInfo.SetValue(obj, Convert.ToDateTime(colValue), null); 99 } 100 else if (pInfos[j].PropertyType.FullName == "System.Nullable`1[[System.DateTime, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089]]") 101 { 102 pInfo.SetValue(obj, Convert.ToDateTime(colValue), null); 103 } 104 else if (pInfos[j].PropertyType.FullName == "System.Nullable`1[[System.Int32, mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089]]") 105 { 106 pInfo.SetValue(obj, Convert.ToInt32(colValue), null); 107 } 108 else if (pInfos[j].PropertyType.FullName == "System.Nullable`1[[System.Int32, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089]]") 109 { 110 pInfo.SetValue(obj, Convert.ToInt32(colValue), null); 111 } 112 else if (pInfos[j].PropertyType.FullName == "System.Nullable`1[[System.Int64, mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089]]") 113 { 114 pInfo.SetValue(obj, Convert.ToInt64(colValue), null); 115 } 116 else if (pInfos[j].PropertyType.FullName == "System.Nullable`1[[System.Int64, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089]]") 117 { 118 pInfo.SetValue(obj, Convert.ToInt64(colValue), null); 119 } 120 else if (pInfos[j].PropertyType.FullName == "System.Nullable`1[[System.Decimal, mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089]]") 121 { 122 pInfo.SetValue(obj, Convert.ToDecimal(colValue), null); 123 } 124 else if (pInfos[j].PropertyType.FullName == "System.Nullable`1[[System.Decimal, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089]]") 125 { 126 pInfo.SetValue(obj, Convert.ToDecimal(colValue), null); 127 } 128 else if (pInfos[j].PropertyType.FullName == "System.Nullable`1[[System.Boolean, mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089]]") 129 { 130 pInfo.SetValue(obj, Convert.ToBoolean(colValue), null); 131 } 132 else if (pInfos[j].PropertyType.FullName == "System.Nullable`1[[System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089]]") 133 { 134 pInfo.SetValue(obj, Convert.ToBoolean(colValue), null); 135 } 136 else 137 { 138 throw new Exception("属性包含不支持的数据类型!"); 139 } 140 } 141 else 142 { 143 pInfo.SetValue(obj, null, null); 144 } 145 } 146 147 #endregion 148 149 #region 根据反射机制从obj对象取值并用该值添加datatable行 150 151 /// <summary> 152 /// 根据反射机制从obj对象取值并用该值添加datatable行 153 /// </summary> 154 /// <param name="obj">obj对象</param> 155 /// <param name="dataTable">dataTable</param> 156 /// <param name="rowIndex">指定行</param> 157 public static void ConvertModelToNewDataRow(object obj, DataTable dataTable, int rowIndex) 158 { 159 //DataTable列为空! 160 if (dataTable.Columns.Count < 1) 161 { 162 throw new Exception("DataTable列为空!"); 163 } 164 165 DataRow dr = dataTable.NewRow(); 166 Type type = obj.GetType(); 167 PropertyInfo[] pInfos = type.GetProperties(); 168 169 try 170 { 171 for (int i = 0; i < dataTable.Columns.Count; i++) 172 { 173 for (int j = 0; j < pInfos.Length; j++) 174 { 175 //全部转换为小写的作用是防止数据库列名的大小写和属性的大小写不一致 176 if (dataTable.Columns[i].ColumnName.ToLower() == pInfos[j].Name.ToLower()) 177 { 178 PropertyInfo pInfo = type.GetProperty(pInfos[j].Name); 179 180 object beanValue = pInfo.GetValue(obj, null); 181 182 //将bean中属性值赋给datarow 183 if (!ObjectIsNull(beanValue)) 184 { 185 dr[i] = beanValue; 186 } 187 else 188 { 189 dr[i] = DBNull.Value; 190 } 191 break; 192 } 193 } 194 } 195 196 dataTable.Rows.InsertAt(dr, rowIndex); 197 dataTable.AcceptChanges(); 198 } 199 catch (Exception ex) 200 { 201 //LogTxt.LogException(ex.Message + "\r\n" + ex.Source + "\r\n" + ex.TargetSite + "\r\n" + ex.StackTrace + "\r\n"); 202 throw ex; 203 } 204 } 205 206 #endregion 207 208 #region 根据反射机制从obj对象取值并赋给datatable的指定行 209 210 /// <summary> 211 /// 根据反射机制从obj对象取值并赋给datatable的指定行 212 /// </summary> 213 /// <param name="obj">obj对象</param> 214 /// <param name="dataTable">dataTable</param> 215 /// <param name="rowIndex">指定行</param> 216 public static void ConvertModelToSpecDataRow(object obj, DataTable dataTable, int rowIndex) 217 { 218 //指定行不存在 219 if (dataTable.Rows.Count < (rowIndex + 1)) 220 { 221 throw new Exception("指定行不存在!"); 222 } 223 224 //DataTable列为空! 225 if (dataTable.Columns.Count < 1) 226 { 227 throw new Exception("DataTable列为空!"); 228 } 229 230 Type type = obj.GetType(); 231 PropertyInfo[] pInfos = type.GetProperties(); 232 233 try 234 { 235 for (int i = 0; i < dataTable.Columns.Count; i++) 236 { 237 for (int j = 0; j < pInfos.Length; j++) 238 { 239 //全部转换为小写的作用是防止数据库列名的大小写和属性的大小写不一致 240 241 if (dataTable.Columns[i].ColumnName.ToLower() == pInfos[j].Name.ToLower()) 242 { 243 PropertyInfo pInfo = type.GetProperty(pInfos[j].Name); 244 object beanValue = pInfo.GetValue(obj, null); 245 246 //将bean中属性值赋给datarow 247 if (!ObjectIsNull(beanValue)) 248 { 249 dataTable.Rows[rowIndex][i] = beanValue; 250 } 251 else 252 { 253 dataTable.Rows[rowIndex][i] = DBNull.Value; 254 } 255 break; 256 } 257 } 258 } 259 dataTable.AcceptChanges(); 260 } 261 catch (Exception ex) 262 { 263 //LogTxt.LogException(ex.Message + "\r\n" + ex.Source + "\r\n" + ex.TargetSite + "\r\n" + ex.StackTrace + "\r\n"); 264 throw ex; 265 } 266 } 267 268 #endregion 269 270 #region 根据对象名返回类实例 271 272 /// <summary> 273 /// 根据对象名返回类实例 274 /// </summary> 275 /// <param name="parObjectName">对象名称</param> 276 /// <returns>对象实例(可强制转换为对象实例)</returns> 277 public static object GetObjectByObjectName(string parObjectName) 278 { 279 Type t = Type.GetType(parObjectName); //找到对象 280 return System.Activator.CreateInstance(t); //实例化对象 281 } 282 283 #endregion 284 285 #region 判断对象是否为空 286 287 /// <summary> 288 /// 判断对象是否为空 289 /// </summary> 290 /// <param name="obj">对象</param> 291 /// <returns></returns> 292 static public bool ObjectIsNull(Object obj) 293 { 294 //如果对象引用为null 或者 对象值为null 或者对象值为空 295 if (obj == null || obj == DBNull.Value || obj.ToString().Equals("") || obj.ToString() == "") 296 { 297 return true; 298 } 299 return false; 300 } 301 302 #endregion 303 304 #region 根据反射机制将DataTable转换为实体集合 305 306 /// <summary> 307 /// 根据反射机制将DataTable转换为实体集合 308 /// </summary> 309 /// <typeparam name="T">实体类型</typeparam> 310 /// <param name="dt">DataTable</param> 311 /// <returns>实体集合</returns> 312 public static List<T> ConvertDataTableToModelList<T>(DataTable dt) 313 { 314 if (dt == null) 315 { 316 return null; 317 } 318 List<T> result = new List<T>(); 319 for (int i = 0; i < dt.Rows.Count; i++) 320 { 321 T t = Activator.CreateInstance<T>(); 322 ConvertDataRowToModel(t, dt, i); 323 result.Add(t); 324 } 325 return result; 326 } 327 328 #endregion 329 330 #region 根据反射机制将DataReader转换为实体集合 331 332 /// <summary> 333 /// 根据反射机制将DataReader转换为实体集合 334 /// </summary> 335 /// <typeparam name="T">实体类型</typeparam> 336 /// <param name="dr">DataReader</param> 337 /// <returns>实体</returns> 338 public static T ConvertDataReaderToModel<T>(MySqlDataReader dr) 339 { 340 T obj = Activator.CreateInstance<T>(); 341 if (dr == null) 342 throw new Exception("制定对象不存在。"); 343 344 if (!dr.Read()) 345 throw new Exception("无法读取数据。"); 346 347 Type type = obj.GetType(); 348 PropertyInfo[] pInfos = type.GetProperties(); 349 for (int i = 0; i < dr.FieldCount; i++) 350 { 351 for (int j = 0; j < pInfos.Length; j++) 352 { 353 if (dr.GetName(i).ToLower() == pInfos[j].Name.ToLower()) 354 { 355 PropertyInfo pInfo = type.GetProperty(pInfos[j].Name); //obj某一属性对象 356 object colValue = dr[i]; //DataTable 列值 357 SetObjectValue(obj, colValue, pInfo, pInfos, j); 358 break; 359 } 360 } 361 } 362 //关闭 363 if (!dr.IsClosed) 364 { 365 dr.Close(); 366 } 367 return (T)obj; 368 } 369 370 #endregion 371 372 /// <summary> 373 /// 通用(调用对象方法前先new一遍对象,故对象的状态无法保留;无用有无参构造函数,并调用无参方法), 374 /// </summary> 375 /// <typeparam name="T"></typeparam> 376 /// <param name="methodName"></param> 377 public static void InvokeMethod<T>(string methodName, object[] param = null) where T : new() 378 { 379 T instance = new T(); 380 MethodInfo method = typeof(T).GetMethod(methodName, new Type[] { }); 381 method.Invoke(instance, param); 382 } 383 384 /// <summary> 385 /// 调用一个具体实例对象的方法,会保留对象状态 386 /// </summary> 387 /// <param name="o"></param> 388 /// <param name="methodName"></param> 389 public static void InvokeMethod(object o, string methodName, object[] param = null) 390 { 391 o.GetType().GetMethod(methodName, new Type[] { }).Invoke(o, param); 392 } 393 }
调用方式
一、将查询到的DataTable转换成对象集合
1 /// <summary> 2 /// 获取列表 3 /// </summary> 4 /// <typeparam name="T">数据类型</typeparam> 5 /// <param name="_connectionString">数据库连接字符串</param> 6 /// <param name="_sql">SQL语句</param> 7 /// <returns>数据集合</returns> 8 public static List<T> GetDataListBySQL<T>(string _connectionString, string _sql) 9 { 10 try 11 { 12 //读取数据库 13 DataTable dt = MySqlHelper.ExecuteDataset(_connectionString, _sql).Tables[0]; 14 //通过反射获取实体集合 15 return ReflectionUtil.ConvertDataTableToModelList<T>(dt); 16 } 17 catch (Exception _ex) 18 { 19 //定义异常处理 20 return default(List<T>); 21 } 22 }
二、将查询到的DataReader转换成对象(以MySQL为例)
1 /// <summary> 2 /// 获取对象 3 /// </summary> 4 /// <typeparam name="T">数据类型</typeparam> 5 /// <param name="_connectionString">数据库连接字符串</param> 6 /// <param name="_sql">SQL语句</param> 7 /// <returns>数据对象</returns> 8 public static T GetObjBySQL<T>(string _connectionString, string _sql) 9 { 10 try 11 { 12 //读取数据库 13 MySqlDataReader dr = MySqlHelper.ExecuteReader(_connectionString, _sql); 14 //通过反射获取实体 15 return ReflectionUtil.ConvertDataReaderToModel<T>(dr); 16 } 17 catch (Exception _ex) 18 { 19 //定义异常处理 20 return default(T); 21 } 22 }
三、调用实体的对象方法
1.调用一个具体实例对象的方法,会保留对象状态。
/// <summary> /// 打开窗体 /// </summary> private void OpenDialog() { Form form = new Form(); ReflectionUtil.InvokeMethod(form, "ShowDialog"); ReflectionUtil.InvokeMethod(form, "Dispose"); }
2.通过类型调用对象的方法,调用时会先new 一个实例,对象的状态无法保留。
1 /// <summary> 2 /// 打开窗体 3 /// </summary> 4 private void OpenDialog() 5 { 6 ReflectionUtil.InvokeMethod<Form>("ShowDialog"); 7 ReflectionUtil.InvokeMethod<Form>("Dispose"); 8 }
标签:
原文地址:http://www.cnblogs.com/Mo-MaTure/p/5398255.html