Getting Difference Between Two Objects With Same P

2020-05-19 00:07发布

I am trying get a list of the changes that were made to an Employee model (object 1) using an EmployeeHistory model (object 2). Basically, there is one single employee record but there are several EmployeeHistory records. Every time something is changed on an Employee a new record is added to the EmployeeHistory table which contains the data of the Employee prior to the change. I want a way to compare each of the EmployeeHistory Records and return a list of strings reporting the changes that were made. So in order to get the list of changes I want to iterate through the list of EmployeeHistory records and compare each EmployeeHistory Record with the previous EmployeeHistory record. And the very last EmployeeHistory record will need to be compared to the current Employee (object 1) record which is very similar in properties. Is there any way to do this without having an insane amount of IF statements comparing the two properties on each of the records?

This is kind of what I am looking for:

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

I already have a method that does all the check for each of the properties but there is going to be a lot more properties added in the future and I tired of having to add the new IF statements and it doesn't seem very efficient.

Here is what a EmployeeMasterHistory Record looks like:

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

Thank you in advance!

标签: c# reflection
2条回答
够拽才男人
2楼-- · 2020-05-19 00:43

Here is a very simple approach using reflection:

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

The output from this example is:

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

This probably needs cleanup, but should get you started down the right path.

查看更多
来,给爷笑一个
3楼-- · 2020-05-19 00:54

The other answer is a good start. But I went ahead and wrote this more-fleshed-out example, so I figured I might as well post it too. This one handles nulls and offers a way to opt-out properties from the comparison. It's still basic, but should get you further, assuming the previously-mentioned library isn't what you want to use.

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>");
                }
            }
        }
    }
}
查看更多
登录 后发表回答