国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 學院 > 開發設計 > 正文

數據模型類對比,用反射做個快樂的程序員

2019-11-15 02:31:16
字體:
來源:轉載
供稿:網友

數據模型類對比,用反射做個快樂的程序員

  曾經看《大話設計模式》的時候說到 反射反射程序員的歡樂,當時我還不太相信 畢竟自己不太會反射。甚至什么時候用反射我也不太知道,只能說查了些資料知道有一些反射這咱東西僅此而已。

  這幾天在做一個人才管理系統,其中有一個讓我糾結的就是 操作日志這塊吧,特別是在修改的時候要記錄每個字段改變前后的情況。好吧,當時有兩個決定方案吧。一、再建了一張和原表相同的結構的唄,再用一個外鍵和原表主鍵連下,做下記錄吧。二、就是在讀取數據的時候存儲兩個Model,一個New Model 一個Old Model唄,然后再對比下。

  最后,由于種種的原因選擇了第二次方式。好吧,竟然用第二種說出來一個問題,怎么對比兩個Model來,難道一個個字段對比嗎?天哪這不噩夢嘛,如果有20個字段我不是要寫20多個對比 20多個IF了,這我不干 這明顯就不是最良的代碼好,不過我也沒什么好的辦法 只能問問度娘、GOOOGLE唄,在這個互聯網的時代,要善用搜索引擎嘛,于是找了下。

一開始代碼應該是這樣的。有兩個實體變量,存放的是修改前和修改后的信息。比如:

InfoModel oldModel=new InfoModel();InfoModel newModel=new InfoModel();

需要遍歷這兩個實體類的全部屬性的值來進行對比,并將有差別的列出來。

  找到一個解決的方案就是使用反射進行對比

//反射遍歷System.Reflection.PRopertyInfo[] mPi = typeof(InfoModel).GetProperties();                for (int i = 0; i < mPi.Length; i++)                {                    System.Reflection.PropertyInfo pi = mPi[i];                    oldValue = pi.GetValue(oldModel, null).ToString();                    newValue = pi.GetValue(newModel, null).ToString();                    if (oldValue !=newValue )                    {                         有差別的列出來                    }                 }}
View Code

  在這里,用一個小問題那就是typeOf是用來放是哪個 MODEL的嘛!還有就是這是什么 oldModel,newModel,如果向這么不就寫死了嘛,每比較一個數據模型類不是都要這樣寫一個方法不是很麻煩,這以前那個對比雖然好了些不會用這么多的IF了 可是還是不能復用的嘛,只知道做軟件設計的做到啥 可維護、可復用、可擴展、靈活性好。

  好吧,這個明顯不能復用的嘛。改改唄,最好做到的就是所有的類都可以用這個方法,此時腦子里瞬間就想起了 泛型。【泛型類和泛型方法同時具備可重用性、類型安全和效率,這是非泛型類和非泛型方法無法具備的。泛型通常用與集合以及作用于集合的方法一起使用。.NET Framework 2.0 版類庫提供一個新的命名空間System.Collections.Generic,其中包含幾個新的基于泛型的集合類。泛型是 C# 2.0 的最強大的功能。通過泛型可以定義類型安全的數據結構,而無須使用實際的數據類型。這能夠顯著提高性能并得到更高質量的代碼,因為您可以重用數據處理算法,而無須復制類型特定的代碼。在概念上,泛型類似于 C++ 模板,但是在實現和功能方面存在明顯差異。】這是從MSDN對泛型的介紹,好吧,我想這個功能應該可以滿足我的要求,把代碼改改唄

 1   public string CompareModel<T>(T newModel, T oldModel)   2         { 3             StringBuilder strLog = new StringBuilder(); 4             System.Reflection.PropertyInfo[] mPi = typeof(T).GetProperties(); 5             for (int i = 0; i < mPi.Length; i++) 6             { 7                 System.Reflection.PropertyInfo pi = mPi[i]; 8                 string strName = string.Empty; 9                 string log = string.Empty;10                 if (pi.GetValue(oldModel, null) != null && pi.GetValue(newModel, null) != null)11                 {12                     string name = pi.Name;//字段名13                     string oldValue = pi.GetValue(oldModel, null).ToString();//獲取對應字段的值14                     string newValue = pi.GetValue(newModel, null).ToString();15                     if (oldValue != newValue)16                     {//具體差異的操作17                         strLog.AppendFormat("{0}從{1}改為{2}", name, oldValue, newValue);18                     }19                 }20             }21             return strLog.ToString();22         }
View Code

  這樣也可以一一的不同的數據列出來了,可這里還有一個問題就是其中的NAME是英文的啊,總不可能給客戶看英文的吧,再想想辦法唄。在這里看到PropertyInfo 有個GetCustomAttributes 的方面,這不就是可以獲取特性的方法嘛,特性我知道就啊,就想在MVC中Model類里的字段上前的 [Display(Name = "用戶名")] 這種東東嘛,好吧,我也有這個樣的吧,雖然Attributes 是可以自定義的,但我還是小小的懶下使用MVC里的算了,自己寫也太麻煩,自己本身對這個也不太會用嘛,只能算是拿來主義。開心的引用了using System.ComponentModel.DataAnnotations;

 1 using System; 2 using System.ComponentModel.DataAnnotations; 3  4  public class LoginModel 5     { 6         7         [Display(Name = "用戶名")] 8         public string UserName { get; set; } 9 10         public string ExternalLoginData { get; set; }11     }12  /// <summary>13         /// 說明:對比實體類14         /// 時間:2014年2月20日 14:17:4815         /// Auhter:Kim16         /// </summary>17         /// <typeparam name="T"></typeparam>18         /// <param name="newModel"></param>19         /// <param name="oldModel"></param>20         /// <returns></returns>21         public string CompareModel<T>(T newModel, T oldModel) where T : class,new ()22         {23             StringBuilder strLog = new StringBuilder();24             System.Reflection. PropertyInfo[] mPi = typeof(T).GetProperties();25             for (int i = 0; i < mPi.Length; i++)26             {27                 System.Reflection. PropertyInfo pi = mPi[i];28                 string strName = string .Empty;29                 string log=string .Empty;30                 if (pi.GetValue(oldModel, null ) != null && pi.GetValue(newModel, null ) != null)31                 {32 33                     strName = Attributes.GetDisplayInfo<T>(pi.Name);34                     string oldValue = pi.GetValue(oldModel, null).ToString();35                     string newValue = pi.GetValue(newModel, null).ToString();36                     if (oldValue != newValue)37                     {38                         if (GetNameByDictonary(strName, oldValue, newValue, out log))39                             strLog.Append(log);40                         else41                             strLog.AppendFormat("<strong>{0}</strong><span>{0} 從 {1} 改為 {2}</span>&nbsp;&nbsp;", strName, oldValue, newValue);42                     }43                 }44             }45             return strLog.ToString();46         }47 48 49 /// <summary>50         /// 獲取DisplayInfo51         /// </summary>52         /// <param name="t"></param>53         public static string GetDisplayInfo<T>( string name) where T : class,new ()54         {55             Type objType = typeof (T);56             // Using reflection.57             string strName = string .Empty;58             PropertyInfo propInfo = objType.GetProperty(name);59             object[] attrs = propInfo.GetCustomAttributes(typeof (DisplayAttribute), true);  // Reflection.60             // Displaying output.61             if (attrs.Length > 0)62             {63                 DisplayAttribute a = attrs[0] as DisplayAttribute;64                 strName = a.Name;65             }66 67             return strName;68         }
View Code

這樣的代碼也基本的符合要求了,不過小弟在這還有一個不解的地方就是說,有一些數據實體類型的字段是別的表的外鍵嘛,這又要怎么正常在的數據顯示出來哪?希望各位大神 指導一二,各位碼農、碼友們有些好的解決方案 也探討下唄,提出你們的寶貴意見,小弟先在這里謝過了!  

                                  


發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
主站蜘蛛池模板: 百色市| 库伦旗| 百色市| 南安市| 大宁县| 郁南县| 屏边| 会宁县| 广河县| 聊城市| 南投市| 来安县| 辛集市| 海安县| 德兴市| 光山县| 慈溪市| 历史| 雅安市| 江西省| 仁化县| 乌拉特中旗| 武夷山市| 策勒县| 郧西县| 榆中县| 阳高县| 汝南县| 富顺县| 张掖市| 临夏市| 萨迦县| 抚顺市| 安阳市| 邯郸市| 沙田区| 东山县| 麟游县| 武乡县| 汉沽区| 丰宁|