2014-10-17 70 views
9

我想要得到的是被使用的EmployeeHistory模型(對象2)員工模型(對象1)所做的更改列表。基本上,只有一個員工記錄,但有幾個EmployeeHistory記錄。每次在Employee上更改某個新記錄時,都會在EmployeeHistory表中添加新記錄,其中包含更改前的Employee的數據。我想要一種方法來比較每個EmployeeHistory記錄並返回一個字符串列表,報告所做的更改。因此,爲了獲得我想要遍歷EmployeeHistory記錄列表的更改列表,並將每個EmployeeHistory記錄與以前的EmployeeHistory記錄進行比較。最後一個EmployeeHistory記錄需要與當前屬性(對象1)記錄進行比較,該記錄在屬性上非常相似。有沒有辦法做到這一點,而沒有瘋狂的數量比較每個記錄上的兩個屬性的IF語句?獲得兩個物體之間的差異有了相同的屬性

這是什麼樣的,我在尋找:

public List<string> GetEmployeeMasterHistory(Models.EmployeeMaster employee,IEnumerable<EmployeeMasterHistory> employeeHistoryCollection) 
{ 
     foreach (var historyRecord in employeeHistoryCollection) 
     { 
      //Compare historyRecord to EmployeeCollection[historyRecord.Index() - 1] 
     } 
     return null; 
} 

我已經做所有檢查各性能的方法,但將是更大量的屬性在將來添加我厭倦了添加新的IF語句,而且效率不高。

下面是一個EmployeeMasterHistory記錄是這樣的:

public partial class EmployeeMasterHistory 
    { 
     public Nullable<int> EmployeeNumber { get; set; } 
     public Nullable<int> CompanyNumber { get; set; } 
     public string UserName { get; set; } 
     public string Initials { get; set; } 
     public string FirstName { get; set; } 
     public string LastName { get; set; } 
     public string FullName { get; set; } 
     public Nullable<bool> StatusFlag { get; set; } 
     public Nullable<System.DateTime> StartDate { get; set; } 
     public Nullable<System.DateTime> TerminationDate { get; set; } 
     public string Branch { get; set; } 
     public Nullable<int> DepartmentNumber { get; set; } 
     public string Supervisor { get; set; } 
     public Nullable<int> Shift { get; set; } 
     public Nullable<int> UnionNo { get; set; } 
     public string G2ID { get; set; } 
     public Nullable<bool> EnterTimeFl { get; set; } 
     public string Phone { get; set; } 
     public string Extension { get; set; } 
     public string CellPhone { get; set; } 
     public string Email { get; set; } 
     public Nullable<int> PrimaryJobRole { get; set; } 
     public Nullable<int> JobLevel { get; set; } 
     public Nullable<int> JobGroup { get; set; } 
     public string JobTitle { get; set; } 
     public string EmployeeType { get; set; } 
     public string PayType { get; set; } 
     public Nullable<decimal> Rate { get; set; } 
     public Nullable<System.DateTime> LastReviewDate { get; set; } 
     public Nullable<System.DateTime> NextReviewDate { get; set; } 
     public Nullable<System.DateTime> LastPayChangeDate { get; set; } 
     public string EmergencyContact { get; set; } 
     public string EmergencyContactRelationship { get; set; } 
     public string EmergencyContactPhone { get; set; } 
     public Nullable<bool> CPComputer { get; set; } 
     public Nullable<bool> CPPhone { get; set; } 
     public Nullable<bool> CPCreditCard { get; set; } 
     public Nullable<bool> CPGasCard { get; set; } 
     public Nullable<bool> CPKeys { get; set; } 
     public Nullable<bool> CPSecurityCard { get; set; } 
     public Nullable<bool> CPVehicle { get; set; } 
     public Nullable<bool> CPTools { get; set; } 
     public Nullable<bool> CPUniform { get; set; } 
     public string ModBy { get; set; } 
     public Nullable<System.DateTime> ModDate { get; set; } 
     public int ID { get; set; } 
     public string SalesRep { get; set; } 
     public string MiddleName { get; set; } 
     public Nullable<int> ManagerEmpNo { get; set; } 
     public Nullable<bool> TempFl { get; set; } 
     public Nullable<bool> PEWFl { get; set; } 
     public Nullable<bool> PGTFl { get; set; } 
     public Nullable<bool> PMPFl { get; set; } 
     public Nullable<bool> PPGEFl { get; set; } 
     public Nullable<bool> PPGFl { get; set; } 
     public Nullable<bool> PRCFl { get; set; } 
     public Nullable<bool> PTCFl { get; set; } 
     public Nullable<bool> PPFl { get; set; } 
     public Nullable<bool> SWPFl { get; set; } 
     public Nullable<int> PrimaryDivision { get; set; } 
     public string TechGroupID { get; set; } 
     public string TechLevelID { get; set; } 
     public Nullable<bool> TechATD { get; set; } 
     public Nullable<int> ReviewPeriod { get; set; } 
     public Nullable<bool> CorpFl { get; set; } 
    } 

預先感謝您!

+0

聽起來像是一個反射在我頭上的工作。 – 2014-10-17 19:28:54

+0

您可以使用反射來識別要比較的屬性。那麼這只是使用循環而不是爲每個屬性編寫新的if子句的問題。如果您只想比較一些屬性,則可以定義一個自定義屬性,以便選擇用於比較的屬性,或選擇退出。 – 2014-10-17 19:29:21

+0

我對反射做了一些研究,因爲我對它很陌生。我將嘗試使用它來創建解決方案。謝謝你們,這非常有幫助。 – user3788671 2014-10-17 19:34:24

回答

15

這是一個非常簡單的方法使用反射:

 var oOldRecord = new EmployeeMasterHistory(); 
     oOldRecord.EmployeeNumber = 1; 
     var oNewRecord = new EmployeeMasterHistory(); 
     oNewRecord.EmployeeNumber = 2; 
     oNewRecord.CompanyNumber = 3; 

     var oType = oOldRecord.GetType(); 

     foreach (var oProperty in oType.GetProperties()) 
     { 
      var oOldValue = oProperty.GetValue(oOldRecord, null); 
      var oNewValue = oProperty.GetValue(oNewRecord, null); 
      // this will handle the scenario where either value is null 
      if (!object.Equals(oOldValue, oNewValue)) 
      { 
       // Handle the display values when the underlying value is null 
       var sOldValue = oOldValue == null ? "null" : oOldValue.ToString(); 
       var sNewValue = oNewValue == null ? "null" : oNewValue.ToString(); 

       System.Diagnostics.Debug.WriteLine("Property " + oProperty.Name + " was: " + sOldValue + "; is: " + sNewValue); 
      } 
     } 

從這個例子的輸出是:

Property EmployeeNumber was: 1; is: 2 
Property CompanyNumber was: null; is: 3 

這可能需要清理,但應該讓你開始正確的道路。

+0

也許'!的Object.Equals(oOldValue,oNewValue)'? – nrofis 2014-10-17 19:42:26

+0

@nrofis:優秀的建議!在記錄差異時仍然必須處理空值,但這應該稍微容易處理。 – 2014-10-17 19:45:53

+0

非常感謝您 – user3788671 2014-10-17 19:47:27

10

其他答案是一個好的開始。但我繼續寫下這個更加充實的例子,所以我想我也可以發佈它。這個人處理空值,並提供了一種選擇性比較的方法。它仍然是基本的,但應該讓你更進一步,假設前面提到的庫不是你想使用的。

using System; 
using System.Collections.Generic; 
using System.Linq; 
using System.Reflection; 

namespace TestCompareProperties 
{ 
    class Program 
    { 
     class IgnorePropertyCompareAttribute : Attribute { } 

     class A 
     { 
      public int Property1 { get; private set; } 
      public string Property2 { get; private set; } 
      [IgnorePropertyCompare] 
      public bool Property3 { get; private set; } 

      public A(int property1, string property2, bool property3) 
      { 
       Property1 = property1; 
       Property2 = property2; 
       Property3 = property3; 
      } 
     } 

     class PropertyCompareResult 
     { 
      public string Name { get; private set; } 
      public object OldValue { get; private set; } 
      public object NewValue { get; private set; } 

      public PropertyCompareResult(string name, object oldValue, object newValue) 
      { 
       Name = name; 
       OldValue = oldValue; 
       NewValue = newValue; 
      } 
     } 

     private static List<PropertyCompareResult> Compare<T>(T oldObject, T newObject) 
     { 
      PropertyInfo[] properties = typeof(T).GetProperties(); 
      List<PropertyCompareResult> result = new List<PropertyCompareResult>(); 

      foreach (PropertyInfo pi in properties) 
      { 
       if (pi.CustomAttributes.Any(ca => ca.AttributeType == typeof(IgnorePropertyCompareAttribute))) 
       { 
        continue; 
       } 

       object oldValue = pi.GetValue(oldObject), newValue = pi.GetValue(newObject); 

       if (!object.Equals(oldValue, newValue)) 
       { 
        result.Add(new PropertyCompareResult(pi.Name, oldValue, newValue)); 
       } 
      } 

      return result; 
     } 

     static void Main(string[] args) 
     { 
      A[] rga = { new A(1, "1", false), new A(2, "1", true), new A(2, null, false) }; 

      for (int i = 0; i < rga.Length - 1; i++) 
      { 
       Console.WriteLine("Comparing {0} and {1}:", i, i + 1); 
       foreach (PropertyCompareResult resultItem in Compare(rga[i], rga[i+1])) 
       { 
        Console.WriteLine(" Property name: {0} -- old: {1}, new: {2}", 
         resultItem.Name, resultItem.OldValue ?? "<null>", resultItem.NewValue ?? "<null>"); 
       } 
      } 
     } 
    } 
} 
+0

謝謝彼得,我仍然樂於提供建議。我對這個東西比較新,所以看到所有不同的方式都很有趣。 – user3788671 2014-10-17 19:54:48