C#两个Object进行比较,Object里只是简单属性,不存在层级关系还比较好处理,如果遇到多层级的就有点麻烦。

1、简单Object比较

        /// <summary>
        /// 比较字段
        /// </summary>
        /// <param name="beforeUpdateData">原来的值</param>
        /// <param name="afterUpdateData">页面提交的新值</param>
        /// <param name="specialFields">特殊处理字段</param>
        /// <param name="ignoreFields">忽略处理字段</param>
        /// <returns></returns>
        public static List<FieldItem> ComparisonField(Object beforeUpdateData,Object afterUpdateData,List<string> specialFields,List<string> ignoreFields)
        {
            var fieldItems = new List<FieldItem>();
            if (null == afterUpdateData || null == beforeUpdateData) return fieldItems;

            Type type = afterUpdateData.GetType();
            var fields = type.GetProperties(System.Reflection.BindingFlags.Instance | System.Reflection.BindingFlags.Public);
            foreach (var field in fields)
            {// 取得字段的值
                object afterUpdateItem = field.GetValue(afterUpdateData);
                var beforeUpdateItem = beforeUpdateData.GetType().GetProperty(field.Name).GetValue(beforeUpdateData, null);
          if (field.PropertyType.IsValueType || field.PropertyType.Name.StartsWith("String"))
                {
                    // String类型处理

                    // 直接比较是否相等,若不相等直接记录
                    if (afterUpdateItem.ToString() != beforeUpdateItem.ToString())
                    {
                        fieldItems.Add(new FieldItem
                                {
                                    ChangeField = field.Name,
                                    BeforeChangeContent = beforeUpdateItem.ToString(),
                                    AfterChangeContent = afterUpdateItem.ToString(),
                                    Description = "修改"
                                });
                    }
                }
            }        return fieldItems;
        }

2、复杂Object比较

对比 product 与 newProduct 两个Object,以下是修改项:

  1. 修改Name:小米Note -> 小米Note2
  2. 修改Detail中的Price:2299 -> 3399
  3. 修改耳机价格:79 -> 89
  4. 产品子项新增了米兔
    class Program
    {
        static void Main(string[] args)
        {
            var earphoneID = Guid.NewGuid();
             } };
             } };
             } };
             } };

            // 构建产品原始数据
            var beijing = new Province { ID = Guid.NewGuid(), Name = "北京" };
            var mifan1 = new User() { ID = Guid.NewGuid(), UserName = "mifan1", RealName = "北京米粉" };
            var attachmentFiles = new List<AttachmentFile>()
                                      {
                                          }
                                      };

            var id = Guid.NewGuid();
            var detailID = Guid.NewGuid();
            var product = new Product()
                              {
                                  ID = id,
                                  Name = "小米Note",
                                  Detail =  },
                                  Province = beijing,
                                  CreateUser = mifan1,
                                  CreateTime = DateTime.Now,
                                  ProductSubitems = new List<ProductSubitem>() { subitem1, subitem2 },
                                  AttachmentFiles = attachmentFiles
                              };

            var newProduct = new Product()
            {
                ID = id,
                Name = "小米Note2", // 1.修改了Name:小米Note -> 小米Note2
                Detail =  }, // 2.修改了Detail中的Price:2299 -> 3399
                Province = beijing,
                CreateUser = mifan1,
                CreateTime = DateTime.Now,
                ProductSubitems = new List<ProductSubitem>() { rabbit, subitem11, subitem2 }, // 3.修改耳机价格:79 -> 89 | 4.产品子项新增了米兔。
                AttachmentFiles = attachmentFiles
            };

            var comparisonFieldList = Common.ComparisonField(product, newProduct, SpecialFields, IgnoreFields);
            foreach (var fieldItem in comparisonFieldList)
            {
                Console.WriteLine(string.Format("变更字段:{0}, 修改前内容:{1}, 修改后内容:{2}, 描述:{3}", fieldItem.ChangeField, fieldItem.BeforeChangeContent, fieldItem.AfterChangeContent,fieldItem.Description));
            }

            Console.ReadLine();
        }

        /// <summary>
        /// 特殊字段,只做ID比较
        /// </summary>
        public static readonly List<string> SpecialFields = new List<string>()
        {
            "Province","AttachmentFiles"
        };

        /// <summary>
        /// 忽略字段
        /// </summary>
        public static readonly List<string> IgnoreFields = new List<string>()
        {
            "ID",
            "CreateTime",
            "CreateUser"
        }; 

多层级实体:

         /// <summary>
         /// 产品
         /// </summary>
         public class Product
         {
             public Guid ID { get; set; }

             /// <summary>
             /// 名称
             /// </summary>
             public string Name { get; set; }

             /// <summary>
             /// 详情
             /// </summary>
             public Detail Detail { get; set; }

             /// <summary>
             /// 产地
             /// </summary>
             public Province Province { get; set; }

             /// <summary>
             /// 创建用户
             /// </summary>
             public User CreateUser { get; set; }

             public DateTime CreateTime { get; set; }

             /// <summary>
             /// 产品子项
             /// </summary>
             public List<ProductSubitem> ProductSubitems { get; set; }

             /// <summary>
             /// 相关文件
             /// </summary>
             public List<AttachmentFile> AttachmentFiles { get; set; }
         }

         /// <summary>
         /// 用户
         /// </summary>
         public class User
         {
             public Guid ID { get; set; }

             public string UserName { get; set; }

             public string RealName { get; set; }
         }

         /// <summary>
         /// 省份
         /// </summary>
         public class Province
         {
             public Guid ID { get; set; }

             public string Name { get; set; }
         }

         /// <summary>
         /// 介绍
         /// </summary>
         public class Detail
         {
             public Guid ID { get; set; }

             /// <summary>
             /// 介绍
             /// </summary>
             public string Introduce { get; set; }

             /// <summary>
             /// 价格
             /// </summary>
             public double Price { get; set; }
         }

         public class ProductSubitem
         {
             public Guid ID { get; set; }

             public string Name { get; set; }

             /// <summary>
             /// 详情
             /// </summary>
             public Detail Detail { get; set; }
         }

         /// <summary>
         /// 文件(图片、文档)
         /// </summary>
         public class AttachmentFile
         {
             public Guid ID { get; set; }

             public string Name { get; set; }

             public double Size { get; set; }

             public string SavePath { get; set; }
         }

多层级实体

最终匹配结果:

ComparisonField 完整方法:

 namespace ComparisonFieldTest
 {
     public class Common
     {
         /// <summary>
         /// 比较字段
         /// </summary>
         /// <param name="beforeUpdateData">原来的值</param>
         /// <param name="afterUpdateData">页面提交的新值</param>
         /// <param name="specialFields">特殊处理字段</param>
         /// <param name="ignoreFields">忽略处理字段</param>
         /// <returns></returns>
         public static
         List<FieldItem> ComparisonField(Object beforeUpdateData, Object afterUpdateData, List<string> specialFields, List<string> ignoreFields)
         {
             var fieldItems = new List<FieldItem>();
             if (null == afterUpdateData || null == beforeUpdateData)
                 return fieldItems;

             Type type = afterUpdateData.GetType();
             var fields = type.GetProperties(System.Reflection.BindingFlags.Instance | System.Reflection.BindingFlags.Public);
             foreach (var field in fields)
             {
                 // 忽略字段不处理
                 if (ignoreFields.Contains(field.Name))
                 {
                     continue;
                 }

                 // 取得字段的值
                 object afterUpdateItem = field.GetValue(afterUpdateData);
                 var beforeUpdateItem = beforeUpdateData.GetType().GetProperty(field.Name).GetValue(beforeUpdateData, null);

                 // 都为空不比较
                 if (afterUpdateItem == null && beforeUpdateItem == null)
                 {
                     continue;
                 }

                 if (field.PropertyType.IsValueType || field.PropertyType.Name.StartsWith("String"))
                 {
                     // String类型处理

                     // 直接比较是否相等,若不相等直接记录
                     if (afterUpdateItem.ToString() != beforeUpdateItem.ToString())
                     {
                         fieldItems.Add(new FieldItem
                         {
                             ChangeField = field.Name,
                             BeforeChangeContent = beforeUpdateItem.ToString(),
                             AfterChangeContent = afterUpdateItem.ToString(),
                             Description = "修改"
                         });
                     }
                 }
                 else if (field.PropertyType.IsGenericType)
                 {
                     // List类型处理

                     var afterUpdateList = field.GetValue(afterUpdateData, null);
                     var beforeUpdateList = beforeUpdateData.GetType().GetProperty(field.Name).GetValue(beforeUpdateData, null);

                     /*
                      * 判断两个对象是否一致,若一致说明未修改,若不一致说明有修改
                      * 修改有三种情况:新增,修改,删除,通过两次遍历找出
                      */

                     var afterList = afterUpdateList as IEnumerable<object>;
                     var beforeList = beforeUpdateList as IEnumerable<object>;

                     // 1.遍历新的与原数据比较
                     foreach (var afterObj in afterList)
                     {
                         Type tp = afterObj.GetType();
                         var property = tp.Name;

                         var ID = afterObj.GetType().GetProperty("ID").GetValue(afterObj);
                         if (ID == null)
                         {
                             // 1. 新录入项

                             if (specialFields.Contains(field.Name))
                             {
                                 // 新增,特殊处理字段
                                 fieldItems.Add(new FieldItem
                                 {
                                     ChangeField = property,
                                     BeforeChangeContent = string.Empty,
                                     AfterChangeContent = ID.ToString(),
                                     Description = "新增"
                                 });
                             }
                             else
                             {
                                 var properties = afterObj.GetType().GetProperties();
                                 var afterChangeContent = new StringBuilder();
                                 foreach (var propertyInfo in properties)
                                 {
                                     var propertyName = propertyInfo.Name;
                                     var value = propertyInfo.GetValue(afterObj);
                                     afterChangeContent.Append(propertyName + ":" + value + "; ");
                                 }
                                 , afterChangeContent.ToString().Length - );

                                 fieldItems.Add(new FieldItem
                                 {
                                     ChangeField = property,
                                     BeforeChangeContent = string.Empty,
                                     AfterChangeContent = afterChangeContentStr,
                                     Description = "新增"
                                 });
                             }
                         }
                         else
                         {
                             // 2.修改项

                             if (!specialFields.Contains(field.Name))
                             {
                                 var beforeObj = beforeList.FirstOrDefault(b => b.GetType().GetProperty("ID").GetValue(b).ToString() == ID.ToString());
                                 if (beforeObj != null)
                                 {
                                     // 1.判断两个对象是否一致,若一致不管,若不一致再处理

                                     // 递归调用
                                     var result = ComparisonField(beforeObj, afterObj, specialFields, ignoreFields);
                                     if (result.Any())
                                     {
                                         // 修改操作
                                         fieldItems.Add(new FieldItem
                                         {
                                             ChangeField = property,
                                             BeforeChangeContent = string.Join(";", result.Select(t => t.ChangeField + ":" + t.BeforeChangeContent)),
                                             AfterChangeContent = string.Join(";", result.Select(t => t.ChangeField + ":" + t.AfterChangeContent)),
                                             Description = "修改"
                                         });
                                     }
                                 }
                                 else
                                 {
                                     var properties = afterObj.GetType().GetProperties();
                                     var afterChangeContent = new StringBuilder();
                                     foreach (var propertyInfo in properties)
                                     {
                                         var propertyName = propertyInfo.Name;
                                         var value = propertyInfo.GetValue(afterObj);
                                         afterChangeContent.Append(propertyName + ":" + value + "; ");
                                     }
                                     , afterChangeContent.ToString().Length - );

                                     fieldItems.Add(new FieldItem
                                     {
                                         ChangeField = property,
                                         BeforeChangeContent = string.Empty,
                                         AfterChangeContent = afterChangeContentStr,
                                         Description = "新增"
                                     });
                                 }
                             }
                         }
                     }

                     // 2.遍历原数据与新的比较
                     foreach (var beforeObj in beforeList)
                     {
                         var ID = beforeObj.GetType().GetProperty("ID").GetValue(beforeObj);
                         var afterObj = afterList.FirstOrDefault(b => b.GetType().GetProperty("ID").GetValue(b).ToString() == ID.ToString());
                         if (afterObj == null)
                         {
                             // 删除操作

                             if (specialFields.Contains(field.Name))
                             {
                                 // 删除,特殊处理字段
                                 fieldItems.Add(new FieldItem
                                 {
                                     ChangeField = beforeObj.GetType().Name,
                                     BeforeChangeContent = ID.ToString(),
                                     AfterChangeContent = string.Empty,
                                     Description = "删除"
                                 });
                             }
                             else
                             {
                                 var properties = beforeObj.GetType().GetProperties();
                                 var beforeContent = new StringBuilder();
                                 foreach (var propertyInfo in properties)
                                 {
                                     var propertyName = propertyInfo.Name;
                                     var value = propertyInfo.GetValue(beforeObj);
                                     beforeContent.Append(propertyName + ":" + value + "; ");
                                 }
                                 var beforeContentStr = beforeContent.ToString()
                                     .Substring(, beforeContent.ToString().Length - );

                                 fieldItems.Add(new FieldItem
                                 {
                                     ChangeField = beforeObj.GetType().Name,
                                     BeforeChangeContent = beforeContentStr,
                                     AfterChangeContent = string.Empty,
                                     Description = "删除"
                                 });
                             }
                         }
                     }
                 }
                 else if (specialFields.Contains(field.Name))
                 {
                     // 特殊字段处理
                     if (afterUpdateItem != null && beforeUpdateItem == null)
                     {
                         // 第一种情况:新增
                         fieldItems.Add(new FieldItem
                         {
                             ChangeField = field.Name,
                             BeforeChangeContent = string.Empty,
                             AfterChangeContent = afterUpdateItem.GetType().GetProperty("ID").GetValue(afterUpdateItem, null).ToString(),
                             Description = "新增"
                         });
                     }
                     else if (afterUpdateItem == null && beforeUpdateItem != null)
                     {
                         // 第二种情况:删除
                         fieldItems.Add(new FieldItem
                         {
                             ChangeField = field.Name,
                             BeforeChangeContent = beforeUpdateItem.GetType().GetProperty("ID").GetValue(beforeUpdateItem, null).ToString(),
                             AfterChangeContent = string.Empty,
                             Description = "删除"
                         });
                     }
                     else
                     {
                         // 第一种情况:修改
                         var afterId = afterUpdateItem.GetType().GetProperty("ID").GetValue(afterUpdateItem, null);
                         var beforeId = beforeUpdateItem.GetType().GetProperty("ID").GetValue(beforeUpdateItem, null);
                         if (!afterId.Equals(beforeId))
                         {
                             fieldItems.Add(new FieldItem
                             {
                                 ChangeField = field.Name,
                                 BeforeChangeContent = beforeId.ToString(),
                                 AfterChangeContent = afterId.ToString(),
                                 Description = "修改"
                             });
                         }
                     }
                 }
                 else
                 {
                     // 递归调用
                     var result = ComparisonField(beforeUpdateItem, afterUpdateItem, specialFields, ignoreFields);
                     fieldItems.AddRange(result);
                 }
             }
             return fieldItems;
         }
     }

     /// <summary>
     /// 建设项目变更字段记录
     /// </summary>
     public class FieldItem
     {
         /// <summary>
         /// 变更字段
         /// </summary>
         public string ChangeField { get; set; }

         /// <summary>
         /// 修改前内容(针对建设图时,存储建设图ID)
         /// </summary>
         public string BeforeChangeContent { get; set; }

         /// <summary>
         /// 修改后内容(针对建设图时,存储建设图ID)
         /// </summary>
         public string AfterChangeContent { get; set; }

         /// <summary>
         /// 描述
         /// </summary>
         public string Description { get; set; }
     }
 }

Common.ComparisonField 完整方法

示例代码下载:

ComparisonFieldTest.zip

C# 两个Object比较的更多相关文章

  1. JS学习之--比较两个Object数组是否相等

    一.问题 在js中是不能直接用“==”或者“===”来计算两个数组是否相等的,那么就需要对数组的值进行比较: 二.次解决方案 对于比较两个数组次要的方法有如下几种,为什么说是次要解决方案呢?因为它不能 ...

  2. 把两个object对象合并成一个对象 属性名称相同的变为后面对象的值

    object.assign(from,obj)------object.assign(目标对象,被合并的对象)

  3. 如何在Node.js中合并两个复杂对象

    通常情况下,在Node.js中我们可以通过underscore的extend或者lodash的merge来合并两个对象,但是对于像下面这种复杂的对象,要如何来应对呢? 例如我有以下两个object: ...

  4. 在Salesforce中为Object创建Master-Detail(Child-Relationship)关联关系

    在Salesforce中可以将两个Object建立起一对多的关联关系,本篇文章就简单的叙述一下将两个Object(EricSunObj & EricSunObjC)设置成Master-Deta ...

  5. 关于C++中Object所占内存空间探索1

    关于C++中Object所占内存空间探索(一) 有如下问题: 1. 一个空类, class X{ }; 2.类中含有数据成员(Data Member), class X { public: //Fun ...

  6. Object类型转换成自定义类型(向下转型)

    Object类型转换成自定义类型 场景: 从数据库或者别的途径接收对象的时候用Object,但是用的时候怎么object点(方法提示 | alt+'/'),都点不出自定义类型的方法. 比如,数据库查询 ...

  7. salesforce 零基础学习(六十三)Comparable实现Object列表数据的自定义排序

    项目中通常有些需求为需要将某个sObject的数据列表按照某种规则排序显示到前台页面上,但是list上面的sort远远满足不了复杂的功能,此种情况需要自定义比较两个object大小的方法,所以需要创建 ...

  8. JDK核心JAVA源代码解析(1) - Object

    想写这个系列非常久了,对自己也是个总结与提高.原来在学JAVA时.那些JAVA入门书籍会告诉你一些规律还有法则,可是用的时候我们一般非常难想起来,由于我们用的少而且不知道为什么.知其所以然方能印象深刻 ...

  9. 软件项目技术点(1)——d3.interpolateZoom-在两个点之间平滑地缩放平移

    AxeSlide软件项目梳理   canvas绘图系列知识点整理 软件参考d3的知识点 我们在软件中主要用到d3.js的核心函数d3.interpolateZoom - 在两个点之间平滑地缩放平移.请 ...

随机推荐

  1. linux下如何修改weblogic console登陆的用户名和密码

    1. 执行安装目录下config.sh ./config.sh 2.选择  2|Extend an existing WebLogic configuration 3. 别的一路跳过,到修改secur ...

  2. 解决 ERROR: JDWP Transport dt_socket failed to initialize, TRANSPORT_INIT(510)异常

    ERROR: JDWP Transport dt_socket failed to initialize, TRANSPORT_INIT(510) 解决方案: 在java_opts="-Xd ...

  3. 【转载】Debian/Ubuntu常见安装软件错误解决方案

    转载自:http://blog.csdn.net/eqera/article/details/6375293 1.错误: Can't find X includes. Please check you ...

  4. VirtualBox的网络设置(6种方式)

    VirtualBox 可以为每一个虚拟机分配8个网卡.每一个网卡的连接方式可以选为下列之一: Not attached Network Address Translation (NAT) Bridge ...

  5. Android学习笔记之DocumentBuilder的使用....

    PS:当你的才华还撑不起你的野心时,那你需要静下心来学习..... 学习内容: 1.从服务器上获取XML文档... 2.解析XML文档中的内容...   XML文件想必大家都非常的熟悉,可扩展的标记语 ...

  6. DotNetCore跨平台~Startup类的介绍

    新宠儿 DotNetCore是.net5.0版本,之所以不叫.net5.0为的就是不让我们把它与前面的.net混为一淡,它将是真正意义的跨平台开发语言,在网上也有相关介绍,中国的一些大牛也发了相关文章 ...

  7. GridView 用 checkbox 全选并取值

    方法一,用 js 实现 <script type="text/javascript"> //<![CDATA[ function CheckAll(oCheckb ...

  8. 记录php日志

    1.记录PHP错误日志 display_errors与log_errors的区别 display_errors 错误回显,一般常用于开发模式,但是很多应用在正式环境中也忘记了关闭此选项.错误回显可以暴 ...

  9. MyKTV项目总结

    今天和大伙分享一下我的KTV系统,我想大家都有自己独特的魅力,都有自己的风采,都有自己骄傲的一部分. 在这里我就抛砖引玉,聊聊我的KTV项目,希望大家能给出自己的建议.. 首先,我们先了解一下:当我们 ...

  10. Autofac全面解析系列(版本:3.5) – [使用篇(推荐篇):2.解析获取]

    前言 Autofac是一套高效的依赖注入框架. Autofac官方网站:http://autofac.org/ Autofac在Github上的开源项目:https://github.com/auto ...