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

代码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. Netty源码分析(五):EventLoop

    上一篇主要介绍了一下EventLoopGroup,本篇详细看下它的成员EventLoop. 类结构 NioEventLoop继承自SingleThreadEventLoop,而SingleThread ...

  2. XSS漏洞解析(一)

    以前写程序没有怎么关注这些网络安全问题,随着自己写的程序越来越多,开始关注了网络安全了. 一.什么是XSS XSS(Cross-Site Scripting) 跨站脚本是一种经常出现在web应用程序的 ...

  3. shiro源码篇 - shiro的session创建,你值得拥有

    前言 开心一刻 开学了,表弟和同学因为打架,老师让他回去叫家长.表弟硬气的说:不用,我打得过他.老师板着脸对他说:和你打架的那位同学已经回去叫家长了.表弟犹豫了一会依然硬气的说:可以,两个我也打得过. ...

  4. mybatis是如何防止SQL注入的

    mybatis是如何防止SQL注入的 1.首先看一下下面两个sql语句的区别: <select id="selectByNameAndPassword" parameterT ...

  5. c#中的特性Attribute

    一:特性是什么?特性怎么创建怎么使用? 这一章节,我想谈谈c#的特性方面的知识,特性大家在工作开发中都很熟悉,比如我们经常见到的 1:key Display --EF 2:Import 3:HttpG ...

  6. Java编译与反编译

    Javac是一种编译器,它的作用是将符合Java语言规范的源代码转化成符合Java虚拟机规范的Java字节码. 一.编译过程 词法分析:找出源代码中的所有关键字,生成Token流 语法分析:检查Tok ...

  7. [转]angular使用Md5加密

    本文转自:https://www.cnblogs.com/waitingbar/p/7527928.html 一.现象 用户登录时需要记住密码的功能,在前端需要对密码进行加密处理,增加安全性 二解决 ...

  8. [转]GitLab Continuous Integration (GitLab CI/CD)

    本文转自:https://docs.gitlab.com/ee/ci/README.html GitLab Continuous Integration (GitLab CI/CD) The bene ...

  9. 第一册:lesson thirty five。

    原文: Our village . This is a photograph of our village. Our village is in  a valley. It is between to ...

  10. mysql函数技巧整理

    IF(expr,v1,v2) expr表达式为true时返回v1,否则返回v2 IFNULL(v1,v2) 如果v1为NULL,返回v2 :v1不为NULL 则返回v1 CASE expr WHEN ...