2014-10-17 71 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