【问题标题】:Getting Difference Between Two Objects With Same Properties获取具有相同属性的两个对象之间的差异
【发布时间】:2014-10-17 19:26:53
【问题描述】:

我正在尝试使用 EmployeeHistory 模型(对象 2)获取对 Employee 模型(对象 1)所做的更改的列表。基本上,只有一个员工记录,但有多个 EmployeeHistory 记录。每次对 Employee 进行更改时,都会将一条新记录添加到 EmployeeHistory 表中,其中包含更改之前的 Employee 数据。我想要一种方法来比较每个 EmployeeHistory Records 并返回一个报告所做更改的字符串列表。因此,为了获取更改列表,我想遍历 EmployeeHistory 记录列表并将每个 EmployeeHistory Record 与之前的 EmployeeHistory 记录进行比较。最后一条 EmployeeHistory 记录需要与当前的 Employee(对象 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 Record 的样子:

 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; }
    }

提前谢谢你!

【问题讨论】:

    标签: c# reflection


    【解决方案1】:

    这是一个使用反射的非常简单的方法:

            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
    

    这可能需要清理,但应该能让你走上正确的道路。

    【讨论】:

      【解决方案2】:

      另一个答案是一个好的开始。但是我继续写了这个更充实的例子,所以我想我也可以发布它。这个处理空值并提供一种从比较中选择退出属性的方法。它仍然是基本的,但应该让您更进一步,假设前面提到的库不是您想要使用的。

      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>");
                      }
                  }
              }
          }
      }
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2013-04-12
        • 1970-01-01
        • 2016-09-15
        • 2021-02-25
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多