C# 获取具有相同属性的两个对象之间的差异
我正在尝试使用EmployeeHistory模型(对象2)获取对员工模型(对象1)所做更改的列表。基本上,只有一个员工记录,但有多个员工历史记录。每次对员工进行更改时,都会将一条新记录添加到EmployeeHistory表中,该表包含更改前员工的数据。我想要一种方法来比较每个EmployeeHistory记录,并返回报告所做更改的字符串列表。因此,为了得到变更列表,我想遍历EmployeeHistory记录列表,并将每个EmployeeHistory记录与以前的EmployeeHistory记录进行比较。最后一个EmployeeHistory记录需要与属性非常相似的当前雇员(对象1)记录进行比较。有没有什么方法可以做到这一点,而不需要大量的IF语句来比较每个记录上的两个属性 这正是我想要的:C# 获取具有相同属性的两个对象之间的差异,c#,reflection,C#,Reflection,我正在尝试使用EmployeeHistory模型(对象2)获取对员工模型(对象1)所做更改的列表。基本上,只有一个员工记录,但有多个员工历史记录。每次对员工进行更改时,都会将一条新记录添加到EmployeeHistory表中,该表包含更改前员工的数据。我想要一种方法来比较每个EmployeeHistory记录,并返回报告所做更改的字符串列表。因此,为了得到变更列表,我想遍历EmployeeHistory记录列表,并将每个EmployeeHistory记录与以前的EmployeeHistory记录
public List<string> GetEmployeeMasterHistory(Models.EmployeeMaster employee,IEnumerable<EmployeeMasterHistory> employeeHistoryCollection)
{
foreach (var historyRecord in employeeHistoryCollection)
{
//Compare historyRecord to EmployeeCollection[historyRecord.Index() - 1]
}
return null;
}
公共列表GetEmployeeMasterHistory(Models.EmployeeMaster employee,IEnumerable EmployeeHistory集合)
{
foreach(employeeHistoryCollection中的var historyRecord)
{
//将historyRecord与EmployeeCollection进行比较[historyRecord.Index()-1]
}
返回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; }
}
公共部分类EmployeeMasterHistory
{
公共可为空的EmployeeNumber{get;set;}
公共可空公司编号{get;set;}
公共字符串用户名{get;set;}
公共字符串首字母{get;set;}
公共字符串名{get;set;}
公共字符串LastName{get;set;}
公共字符串全名{get;set;}
公共可空状态标志{get;set;}
公共可为空的起始日期{get;set;}
公共可为空的终止日期{get;set;}
公共字符串分支{get;set;}
公共可为空的部门编号{get;set;}
公共字符串管理器{get;set;}
公共可空移位{get;set;}
公共可为空的UnionNo{get;set;}
公共字符串G2ID{get;set;}
公共可为空的EnterTimeFl{get;set;}
公用字符串电话{get;set;}
公共字符串扩展名{get;set;}
公共字符串{get;set;}
公共字符串电子邮件{get;set;}
公共可为空的PrimaryJobRole{get;set;}
公共可为空的作业级别{get;set;}
可为空的公共作业组{get;set;}
公共字符串JobTitle{get;set;}
公共字符串EmployeeType{get;set;}
公共字符串PayType{get;set;}
公共可空速率{get;set;}
公共可为空的LastReviewDate{get;set;}
公共可为空的NextReviewDate{get;set;}
公共可为空的LastPayChangeDate{get;set;}
公共字符串紧急联系人{get;set;}
公共字符串EmergencyContactRelationship{get;set;}
公共字符串EmergencyContactPhone{get;set;}
公共可为空的CPComputer{get;set;}
公共可空CPPhone{get;set;}
公共可为空的CPCredit卡{get;set;}
公共可为空的CPGasCard{get;set;}
公共可为空的CPKeys{get;set;}
公共可为空的CPSecurityCard{get;set;}
公共可为空的CPVehicle{get;set;}
公共可为空的CPTools{get;set;}
公共可空CPUniform{get;set;}
公共字符串ModBy{get;set;}
公共可为空的ModDate{get;set;}
公共int ID{get;set;}
公共字符串SalesRep{get;set;}
公共字符串MiddleName{get;set;}
公共可为空的ManagerEmpNo{get;set;}
公共可为空的TempFl{get;set;}
公共可为空的PEWFl{get;set;}
公共可空PGTFl{get;set;}
公共可空PMPFl{get;set;}
公共可空PPGEFl{get;set;}
公共可空PPGFl{get;set;}
公共可为空的PRCFl{get;set;}
公共可空PTCFl{get;set;}
公共可空PPFl{get;set;}
公共可空SWPFl{get;set;}
公共可空主除法{get;set;}
公共字符串TechGroupID{get;set;}
公共字符串TechLevelID{get;set;}
公共可为空的TechATD{get;set;}
公共可空的ReviewPeriod{get;set;}
公共可空CorpFl{get;set;}
}
提前谢谢你 下面是一个使用反射的非常简单的方法:
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
这可能需要清理,但应该让您开始走正确的道路。另一个答案是一个良好的开端。但我继续写了这个更加充实的例子,所以我想我也可以把它贴出来。这个函数处理空值,并提供一种从比较中选择退出属性的方法。它仍然是基本的,但应该会让您更进一步,假设前面提到的库不是您想要使用的
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>");
}
}
}
}
}
使用系统;
使用System.Collections.Generic;
使用System.Linq;
运用系统反思;
命名空间TestCompareProperties
{
班级计划
{
类IgnorePropertyCompareAttribute:属性{}
甲级
{
公共int属性1{get;私有集;}
公共字符串属性2{get;private set;}
[IgnorePropertyCompare]
公共布尔属性3{get;private set;}
公共A(int属性1、字符串属性2、布尔属性3)
{
Property1=Property1;
Property2=属性