2014-10-17 14 views
9

Sto cercando di ottenere un elenco delle modifiche apportate a un modello Employee (oggetto 1) utilizzando un modello EmployeeHistory (oggetto 2). Fondamentalmente, c'è un solo record di dipendente, ma ci sono diversi record di EmployeeHistory. Ogni volta che qualcosa viene cambiato su un Dipendente, un nuovo record viene aggiunto alla tabella EmployeeHistory che contiene i dati del Dipendente prima della modifica. Voglio un modo per confrontare ciascuno dei record EmployeeHistory e restituire un elenco di stringhe che riportano le modifiche apportate. Quindi, per ottenere l'elenco delle modifiche, desidero ripetere l'elenco dei record EmployeeHistory e confrontare ciascun record EmployeeHistory con il precedente record EmployeeHistory. E l'ultimo record EmployeeHistory dovrà essere confrontato con il record Employee (oggetto 1) corrente che è molto simile nelle proprietà. C'è un modo per farlo senza avere una quantità folle di istruzioni IF che confrontano le due proprietà su ciascuno dei record?Ottenere la differenza tra due oggetti con le stesse proprietà

questo è una specie di quello che sto cercando:

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

ho già un metodo che fa tutto il controllo per ciascuna delle proprietà, ma ci sarà molto più proprietà aggiunte in futuro e mi stanco di dover aggiungere le nuove istruzioni IF e non sembra molto efficiente.

Ecco ciò che un record EmployeeMasterHistory assomiglia:

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

Grazie in anticipo!

+0

Suona come un lavoro di riflessione dalla cima della mia testa. –

+0

È possibile utilizzare la riflessione per identificare le proprietà da confrontare. Quindi è solo questione di usare un ciclo invece di scrivere una nuova clausola if per ogni proprietà. Se si desidera confrontare solo alcune proprietà, è possibile definire un Attributo personalizzato, sia per l'attivazione delle proprietà per il confronto, sia per la disattivazione. –

+0

Ho fatto delle ricerche sulla riflessione perché ne sono nuovo. Ho intenzione di provare e creare una soluzione utilizzandolo. Grazie ragazzi, è molto utile. – user3788671

risposta

15

Ecco un approccio molto semplice utilizzando la riflessione:

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

L'output di questo esempio è:

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

Questo probabilmente ha bisogno di pulizia, ma dovrebbe iniziare verso il basso la strada giusta.

+0

Forse '! Oggetto.Equals (oOldValue, oNewValue)'? – nrofis

+0

@nrofis: ottimo suggerimento!Devono ancora occuparsi di null quando si registrano le differenze, ma dovrebbe essere leggermente più semplice da gestire. –

+0

Grazie mille – user3788671

10

L'altra risposta è un buon inizio. Ma sono andato avanti e ho scritto questo esempio più dettagliato, quindi ho pensato che anche io avrei potuto postarlo. Questo gestisce i valori nulli e offre un modo per disattivare le proprietà dal confronto. È ancora di base, ma dovresti farti ulteriormente, assumendo che la libreria menzionata in precedenza non sia quella che vuoi usare.

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

Grazie Peter, sono ancora aperto ai suggerimenti. Sono più recente a questa roba quindi è interessante vedere tutti i diversi modi per farlo. – user3788671

Problemi correlati