当前项目需要记录变更记录,即用户在进行编辑后,将变更操作记录下来。但是数据没有发生变化,则不记录。

代码1:(仅仅返回是否变化的标识)

    /// <summary>
/// 反射对比实体属性变更
/// </summary>
/// <typeparam name="T"></typeparam>
public class CompareEntry<T>
{
/// <summary>
/// 编辑之前的对象和编辑后的对象进行对比
/// </summary>
/// <returns></returns>
public bool CompareDTO(T BeforeDTO, T AfterDTO)
{
bool IsEqual = true; if (BeforeDTO == null || AfterDTO == null)
{
IsEqual = false;
}
else if (BeforeDTO.Equals(DBNull.Value) || AfterDTO.Equals(DBNull.Value))
{
IsEqual = false;
}else if (BeforeDTO.GetType() != AfterDTO.GetType())
{
IsEqual = false;
return IsEqual;
}
else if (BeforeDTO is int || BeforeDTO is short || BeforeDTO is long || BeforeDTO is float || BeforeDTO is double || BeforeDTO is decimal)
{
//int 01与1
if (BeforeDTO is int)
{
if (Convert.ToInt32(BeforeDTO) != Convert.ToInt32(AfterDTO))
{
IsEqual = false;
}
}
else if (BeforeDTO is short)
{
if (Convert.ToInt16(BeforeDTO) != Convert.ToInt16(AfterDTO))
{
IsEqual = false;
}
}
else if (BeforeDTO is long)
{
if (Convert.ToInt64(BeforeDTO) != Convert.ToInt64(AfterDTO))
{
IsEqual = false;
}
}
else if (BeforeDTO is float)
{
if (Convert.ToSingle(BeforeDTO) != Convert.ToSingle(AfterDTO))
{
IsEqual = false;
}
}
else if (BeforeDTO is double)
{
if (Convert.ToDouble(BeforeDTO) != Convert.ToDouble(AfterDTO))
{
IsEqual = false;
}
}
else if (BeforeDTO is decimal)
{
if (Convert.ToDecimal(BeforeDTO) == Convert.ToDecimal(AfterDTO))
{
IsEqual = false;
}
}
}
else
{
var beforeMembers = BeforeDTO.GetType().GetProperties();
var afterMembers = AfterDTO.GetType().GetProperties();
for (int i = ; i < beforeMembers.Length; i++)
{
var beforeVal = beforeMembers[i].GetValue(BeforeDTO, null);
var afterVal = afterMembers[i].GetValue(AfterDTO, null);
var beforeValue = beforeVal == null ? null : beforeVal.ToString();
var afterValue = afterVal == null ? null : afterVal.ToString();
if (beforeValue != afterValue)
{
IsEqual = false;
break;
}
}
} return IsEqual;
}
}

调整后的代码:(返回标识以及详细变更记录)

  /// <summary>
///
/// </summary>
public class CompareResult
{
/// <summary>
///
/// </summary>
public bool IsChange { get; set; }
/// <summary>
/// 变跟内容
/// </summary>
public string ChangeContent { get; set; }
} /// <summary>
/// 对比实体属性变更(利用反射)
/// </summary>
public class CompareEntry
{
/// <summary>
///
/// </summary>
/// <returns></returns>
public CompareResult CompareDTO(object BeforeDTO, object AfterDTO)
{
CompareResult result = new CompareResult();
bool b = false; if (BeforeDTO == null && AfterDTO != null)
{
b = true;
}
else if (BeforeDTO != null && AfterDTO == null)
{
b = true;
}
else if (BeforeDTO.Equals(DBNull.Value) && !AfterDTO.Equals(DBNull.Value))
{
b = true;
}
else if (!BeforeDTO.Equals(DBNull.Value) && AfterDTO.Equals(DBNull.Value))
{
b = true;
}
else if (BeforeDTO.GetType() != AfterDTO.GetType())
{
result.IsChange = true;
return result;
}
else if (BeforeDTO is int || BeforeDTO is short || BeforeDTO is long || BeforeDTO is float || BeforeDTO is double || BeforeDTO is decimal)
{
if (BeforeDTO is int)
{
if (Convert.ToInt32(BeforeDTO) != Convert.ToInt32(AfterDTO))
{
b = true;
}
}
else if (BeforeDTO is short)
{
if (Convert.ToInt16(BeforeDTO) != Convert.ToInt16(AfterDTO))
{
b = true;
}
}
else if (BeforeDTO is long)
{
if (Convert.ToInt64(BeforeDTO) != Convert.ToInt64(AfterDTO))
{
b = true;
}
}
else if (BeforeDTO is float)
{
if (Convert.ToSingle(BeforeDTO) != Convert.ToSingle(AfterDTO))
{
b = true;
}
}
else if (BeforeDTO is double)
{
if (Convert.ToDouble(BeforeDTO) != Convert.ToDouble(AfterDTO))
{
b = true;
}
}
else if (BeforeDTO is decimal)
{
if (Convert.ToDecimal(BeforeDTO) == Convert.ToDecimal(AfterDTO))
{
b = true;
}
}
}
else
{
StringBuilder content = new StringBuilder();
var beforeMembers = BeforeDTO.GetType().GetProperties();
var afterMembers = AfterDTO.GetType().GetProperties();
for (int i = ; i < beforeMembers.Length; i++)
{
var beforeVal = beforeMembers[i].GetValue(BeforeDTO, null);
var afterVal = afterMembers[i].GetValue(AfterDTO, null);
var beforeValue = beforeVal == null ? null : beforeVal.ToString();
var afterValue = afterVal == null ? null : afterVal.ToString();
if (beforeValue != afterValue)
{
b = true;
content.Append(beforeMembers[i].Name+"("+ beforeValue+"->"+afterValue+")");
}
}
result.IsChange = b;
result.ChangeContent = content.ToString();
} return result;
}
}

注意,引用类型进行对比的时候,需要在编辑之前对对象进行拷贝,让拷贝的对象与编辑后的对象进行对比。(因为引用类型不同于值类型,值类型每次操作都会产生一个新的对象,而引用类型在new一个新对象赋值时,其实是在堆上创建了一个内存地址,指向的仍然是原对象,对它操作原对象也会发生变化。所以只有通过拷贝复制一个新对象)

c#判断两个对象和对象中的属性是否相同(以及记录对象中的哪些字段,和详细的改变情况)的更多相关文章

  1. 将source类中的属性值赋给target类中对应的属性

    /** * 对象的属性值拷贝 * <p> * 将source对象中的属性值赋值到target对象中的属性,属性名一样,类型一样 * <p> * example: * <p ...

  2. LinearLayout的gravity属性以及其子元素的layout_gravity何时有效;RelativeLayout如何调整其子元素位置只能用子元素中的属性来控制,用RelativeLayout中的gravity无法控制!!!

    LinearLayout的gravity属性以及其子元素的layout_gravity何时有效:RelativeLayout如何调整其子元素位置只能用子元素中的属性来控制,用RelativeLayou ...

  3. 微信小程序:给data中对象中的属性设置值与给data中的属性或对象或数组设置值的区别

    一.给data中的属性或对象或数组设置值,属性名不需要加引号 this.setData({ material: param, // 这里material为对象 } this.setData({   d ...

  4. 修改表单元素中placeholder属性样式、清除IE浏览器中input元素的清除图标和眼睛图标

    一.修改input元素placeholder属性样式 在做项目的时候,一般表单元素的placeholder属性样式都是使用浏览器默认的,但有时候为了追求设计上的美感需要修表单元素的placeholde ...

  5. 用泛型方法Java从实体中提取属性值,以及在泛型方法中的使用

    public <T> T getFieldValue(Object target, String fieldName, Class<T> typeName) { try { O ...

  6. JavaScript 深入了解对象中的属性

    本篇主要介绍JS中对象的属性,包括:属性的分类.访问方式.检测属性.遍历属性以及属性特性等内容. 目录 1. 介绍:描述属性的命名方式.查找路径以及分类 2. 属性的访问方式:介绍'.'访问方式.'[ ...

  7. 在 WPF 中获取一个依赖对象的所有依赖项属性

    原文:在 WPF 中获取一个依赖对象的所有依赖项属性 本文介绍如何在 WPF 中获取一个依赖对象的所有依赖项属性. 本文内容 通过 WPF 标记获取 通过设计器专用方法获取 通过 WPF 标记获取 p ...

  8. 遍历js对象中的属性

    可以使用js自带的for in.也可以使用Ext JS中的方法来遍历js对象中的属性 代码如下: /** 遍历对象 */ var person = {name:'张泰松',age:28}; //js方 ...

  9. 深入理解JavaScript中的属性和特性

    深入理解JavaScript中的属性和特性 JavaScript中属性和特性是完全不同的两个概念,这里我将根据自己所学,来深入理解JavaScript中的属性和特性. 主要内容如下: 理解JavaSc ...

随机推荐

  1. Python快速学习10: 循环的对象及设计 (生活的规律)

    前言 系列文章:[传送门] 生活逐渐规律,按时睡觉.今天写博客,明天补时间看会书.慢慢的时间很珍惜 我很喜欢! 时钟就像个循环体,我们将它融入生活. 正文 循环对象的并不是随着Python的诞生就存在 ...

  2. 绑定Github上的个人博客到Godaddy域名

    大家好,这里是「 从零开始学 Web 系列教程 」,并在下列地址同步更新...... github:https://github.com/Daotin/Web 微信公众号:Web前端之巅 博客园:ht ...

  3. 在关闭页面时自动清除Session cookie,页面缓存

    在默认情况下,session对象在关闭浏览器后并不是立刻被销毁,因此,为了考虑系统的安全性,在用户退出时,需要即刻清除session对象,防止他人盗用session对象中的信息. 清除session对 ...

  4. 部署vmware-vcsa 6.5

    介绍一下vcsa vsphere的两个最重要的组件是esxi和vcenter server,esxi是虚拟化主机管理软件,而vcenter server则是管理.组织多台esxi主机的管理中心. es ...

  5. [转]nodeJS中redis初步使用

    本文转自:https://blog.csdn.net/frankenjoy123/article/details/55209637 Node.js下使用Redis,首先: 1.有一台安装了Redis的 ...

  6. [转]Angular引入第三方库

    本文转自: https://blog.csdn.net/yuzhiqiang_1993/article/details/71215232 版权声明:本文为博主原创文章,转载请注明地址.如果文中有什么纰 ...

  7. Web下的HTTPS应用

    ---------------------------------------------------------------------------------------------------- ...

  8. Git合并指定文件到另一个分支

    经常被问到如何从一个分支合并特定的文件到另一个分支.其实,只合并你需要的那些commits,不需要的commits就不合并进去了. 合并某个分支上的单个commit 首先,用git log或sourc ...

  9. 45.work_struct和delayed_work的工作队列使用

    介绍 在中断处理中,经常用到工作队列,这样便能缩短中断处理时的时间 中断中通过调用schedule_work(work)来通知内核线程,然后中断结束后,再去继续执行work对应的func函数 示例 当 ...

  10. js 点击文本框,预览选择图片

    点击文件选择框,选择图片文件,通过FileReader对象,读取图片文件中的内容,存放于result中,具体代码如下 <input type="file" onchange= ...