Skip to content

加了一个ModelMapHelper类 #341

Description

@xcanel
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Reflection;
using System.Text;

namespace SEP.Common
{
    /// <summary>
    /// 对象转换
    /// </summary>
    public class ModelMapHelper
    {
        /// <summary>
        /// 合并数据 把origin的数据合并到obj中
        /// </summary>
        /// <typeparam name="T1">原类型</typeparam>
        /// <typeparam name="T2">目标类型</typeparam>
        /// <param name="origin">原对象</param>
        /// <param name="obj">目标对象</param>
        /// <param name="allowEmployee">是否允许null或空值</param>
        public static void GetModelMerge<T1, T2>(T1 origin, T2 obj, bool allowEmployee = true)
        {
            var OriginPropertyList = GetPropertyValue<T1>(origin);
            if (obj != null)
            {
                Dictionary<string, string> propertyValue = new Dictionary<string, string>();
                Type type = obj.GetType();
                PropertyInfo[] propertyInfos = type.GetProperties();
                foreach (PropertyInfo property in propertyInfos)
                {
                    string value = "";
                    if (OriginPropertyList.TryGetValue(property.Name, out value))
                    {
                        if (!property.PropertyType.IsGenericType)
                        {
                            //非泛型
                            if (!string.IsNullOrEmpty(value) || allowEmployee)
                                property.SetValue(obj, string.IsNullOrEmpty(value) ? null : Convert.ChangeType(value, property.PropertyType), null);
                        }
                        else
                        {
                            //泛型Nullable<>
                            Type genericTypeDefinition = property.PropertyType.GetGenericTypeDefinition();
                            if (genericTypeDefinition == typeof(Nullable<>))
                            {
                                if (!string.IsNullOrEmpty(value) || allowEmployee)
                                    property.SetValue(obj, string.IsNullOrEmpty(value) ? null : Convert.ChangeType(value, Nullable.GetUnderlyingType(property.PropertyType)), null);
                            }
                        }
                    }
                }

            }
        }

        /// <summary>
        /// 获取对象的属性和值
        /// </summary>
        /// <param name="obj">对象</param>
        /// <returns>返回属性与值一一对应的字典</returns>
        public static Dictionary<string, string> GetPropertyValue<T>(T obj)
        {
            if (obj != null)
            {
                Dictionary<string, string> propertyValue = new Dictionary<string, string>();
                Type type = obj.GetType();
                PropertyInfo[] propertyInfos = type.GetProperties();

                foreach (PropertyInfo item in propertyInfos)
                {
                    switch (item.PropertyType.FullName)
                    {
                        case "System.Int32":
                            propertyValue.Add(item.Name, (item.GetValue(obj, null) == null ? "" : item.GetValue(obj, null)).ObjToInt().ToString());
                            break;
                        case "System.Decimal":
                            propertyValue.Add(item.Name, (item.GetValue(obj, null) == null ? "" : item.GetValue(obj, null)).ObjToDecimal().ToString());
                            break;
                        default:
                            propertyValue.Add(item.Name, (item.GetValue(obj, null) == null ? "" : item.GetValue(obj, null)).ToString());
                            break;
                    }
                }

                return propertyValue;
            }
            return null;
        }


        /// <summary>
        /// 获取对象的主键列表
        /// </summary>
        /// <param name="obj">对象</param>
        /// <returns>返回主键列表</returns>
        public static List<string> GetPropertyPrimaryKeys<T>(T obj)
        {
            if (obj != null)
            {
                List<string> list = new List<string>();
                Type type = obj.GetType();
                PropertyInfo[] propertyInfos = type.GetProperties();

                foreach (PropertyInfo item in propertyInfos)
                {
                    if (item.CustomAttributes != null)
                    {
                        foreach (var attr in item.CustomAttributes)
                        {
                            foreach (var info in attr.NamedArguments)
                            {
                                if (info.MemberName == "IsPrimaryKey"
                                    && (bool)info.TypedValue.Value
                                    && !list.Contains(item.Name))
                                    list.Add(item.Name);
                            }
                        }
                    }
                }

                return list;
            }
            return null;
        }

        /// <summary>
        /// 比较2个对象,不同对象则只比较相同字段
        /// </summary>
        /// <typeparam name="T1"></typeparam>
        /// <typeparam name="T2"></typeparam>
        /// <param name="origin"></param>
        /// <param name="obj"></param>
        /// <param name="oType"></param>
        /// <param name="parts"></param>
        /// <returns></returns>
        public static string CompareModel<T1, T2>(T1 origin, T2 obj, AppEnum.OperationType oType, string parts = "", bool hasPrimaryKey = true) where T1 : class, new() where T2 : class, new()
        {
            if (origin == null)
                origin = new T1();
            if (obj == null)
                obj = new T2();

            if (!string.IsNullOrEmpty(parts))
                parts = "," + parts;
            StringBuilder diffColumns = new StringBuilder(); //差异数据
            var OriginPropertyList = GetPropertyValue<T1>(origin);
            var objPropertyList = GetPropertyValue<T2>(obj);

            var primaryKeysList = GetPropertyPrimaryKeys<T1>(origin);
            StringBuilder diffKeyColumns = new StringBuilder();
            foreach (var originItem in OriginPropertyList)
            {
                if (
                    (oType == AppEnum.OperationType.Update ||
                     oType == AppEnum.OperationType.Add) &&
                    (
                     originItem.Key.StartsWith("Update") ||
                     originItem.Key.StartsWith("Create") ||
                     originItem.Key.EndsWith("Code")
                    )) //更新时 不需要记录创建信息
                {
                    continue;
                }

                string value = "";
                if (objPropertyList.TryGetValue(originItem.Key, out value))
                {
                    if (primaryKeysList.Contains(originItem.Key))
                    {
                        if (RegexExpressHelper.IsValidDemical(value) && value.ObjToDecimal() > 0)
                            diffKeyColumns.AppendLine("\"主键[" + originItem.Key + "]\":\"值[" + value + "]\"");
                    }
                    if (originItem.Value != value)
                    {
                        bool isSameNum = false;
                        if (RegexExpressHelper.IsValidDemical(originItem.Value) && RegexExpressHelper.IsValidDemical(value))
                        {
                            if (originItem.Value.ObjToDecimal() == value.ObjToDecimal())
                                isSameNum = true;
                        }
                        if (!isSameNum)
                        {
                            if (oType == AppEnum.OperationType.Add)
                            {
                                if (diffColumns.Length == 0)
                                    diffColumns.AppendLine("\"" + originItem.Key + "\":\"新增值[" + value + "]\"");
                                else
                                    diffColumns.AppendLine(",\"" + originItem.Key + "\":\"新增值[" + value + "]\"");
                            }
                            else if (oType == AppEnum.OperationType.Update)
                            {
                                if (diffColumns.Length == 0)
                                    diffColumns.AppendLine("\"" + originItem.Key + "\":\"由[" + (string.IsNullOrEmpty(originItem.Value) ? "空值" : originItem.Value) + "]修改为[" + (string.IsNullOrEmpty(value) ? "空值" : value) + "]\"");
                                else
                                    diffColumns.AppendLine(",\"" + originItem.Key + "\":\"由[" + (string.IsNullOrEmpty(originItem.Value) ? "空值" : originItem.Value) + "]修改为[" + (string.IsNullOrEmpty(value) ? "空值" : value) + "]\"");
                            }
                            else
                            {
                                if (diffColumns.Length == 0)
                                    diffColumns.AppendLine("\"" + originItem.Key + "\":\"值[" + (string.IsNullOrEmpty(originItem.Value) ? "空值" : originItem.Value) + "]\"");
                                else
                                    diffColumns.AppendLine(",\"" + originItem.Key + "\":\"值[" + (string.IsNullOrEmpty(originItem.Value) ? "空值" : originItem.Value) + "]\"");
                            }
                        }
                    }
                }
            }
            if (diffColumns.Length > 0)
            {
                if (diffKeyColumns.Length > 0)
                    return "{" + diffKeyColumns.ToString() + "," + diffColumns.ToString() + parts + "}";
                else
                    return "{" + diffColumns.ToString() + parts + "}";
            }
            else
                return "";
        }

        public static string CompareModelMultiple<T1, T2>(List<T1> origin, List<T2> obj, AppEnum.OperationType oType) where T1 : class, new() where T2 : class, new()
        {
            if (origin == null && obj == null)
                return null;

            if (origin == null || origin.Count == 0)
            {
                origin = new List<T1>();
                for (int i = 0; i < obj.Count; i++)
                    origin.Add(new T1());
            }
            if (obj == null || obj.Count == 0)
            {
                obj = new List<T2>();
                for (int i = 0; i < origin.Count; i++)
                    obj.Add(new T2());
            }


            StringBuilder diffColumnsList = new StringBuilder(); //差异数据
            for (int i = 0; i < origin.Count; i++)
            {
                StringBuilder diffColumns = new StringBuilder();
                var OriginPropertyList = GetPropertyValue<T1>(origin[i]);
                var objPropertyList = GetPropertyValue<T2>(obj[i]);
                foreach (var originItem in OriginPropertyList)
                {
                    if (oType == AppEnum.OperationType.Add && (
                        originItem.Key.Equals("CreateTime") ||
                        originItem.Key.Equals("CreateUser") ||
                        originItem.Key.Equals("CreateUserName") ||
                        originItem.Key.EndsWith("Code")
                        ))
                    {
                        continue;
                    }
                    if (oType == AppEnum.OperationType.Update && (
                        originItem.Key.Equals("UpdateTime") ||
                        originItem.Key.Equals("UpdateUser") ||
                        originItem.Key.Equals("UpdateUserName") ||
                        originItem.Key.EndsWith("Code")
                        ))
                    {
                        continue;
                    }

                    string value = "";
                    if (objPropertyList.TryGetValue(originItem.Key, out value))
                    {
                        if (originItem.Value != value)
                        {
                            bool isSameNum = false;
                            if (RegexExpressHelper.IsValidDemical(originItem.Value) && RegexExpressHelper.IsValidDemical(value))
                            {
                                if (originItem.Value.ObjToDecimal() == value.ObjToDecimal())
                                    isSameNum = true;
                            }
                            if (!isSameNum)
                            {
                                if (oType == AppEnum.OperationType.Add)
                                {
                                    if (diffColumns.Length == 0)
                                        diffColumns.AppendLine("\"" + originItem.Key + "\":\"新增值[" + value + "]\"");
                                    else
                                        diffColumns.AppendLine(",\"" + originItem.Key + "\":\"新增值[" + value + "]\"");
                                }
                                else if (oType == AppEnum.OperationType.Update)
                                {
                                    if (diffColumns.Length == 0)
                                        diffColumns.AppendLine("\"" + originItem.Key + "\":\"由[" + (string.IsNullOrEmpty(originItem.Value) ? "空值" : originItem.Value) + "]修改为[" + (string.IsNullOrEmpty(value) ? "空值" : value) + "]\"");
                                    else
                                        diffColumns.AppendLine(",\"" + originItem.Key + "\":\"由[" + (string.IsNullOrEmpty(originItem.Value) ? "空值" : originItem.Value) + "]修改为[" + (string.IsNullOrEmpty(value) ? "空值" : value) + "]\"");
                                }
                                else
                                {
                                    if (diffColumns.Length == 0)
                                        diffColumns.AppendLine("\"" + originItem.Key + "\":\"值[" + (string.IsNullOrEmpty(originItem.Value) ? "空值" : originItem.Value) + "]\"");
                                    else
                                        diffColumns.AppendLine(",\"" + originItem.Key + "\":\"值[" + (string.IsNullOrEmpty(originItem.Value) ? "空值" : originItem.Value) + "]\"");
                                }
                            }
                        }
                    }
                }
                if (diffColumns.Length > 0)
                {
                    //数据前后添加{} 或者 ,{}
                    if (diffColumnsList.Length > 0)
                        diffColumns.Insert(0, ",{");
                    else
                        diffColumns.Insert(0, "{");
                    diffColumns.Append("}");
                }
                diffColumnsList.Append(diffColumns);
            }

            if (diffColumnsList.Length > 0)
                return "[" + diffColumnsList.ToString() + "]";
            else
                return "";
        }


        /// <summary>
        /// 获取枚举值上的Description特性的说明
        /// </summary>
        /// <typeparam name="T">枚举类型</typeparam>
        /// <param name="obj">枚举值</param>
        /// <returns>特性的说明</returns>
        public static string GetEnumDescription<T>(T obj)
        {
            var type = obj.GetType();
            FieldInfo field = type.GetField(Enum.GetName(type, obj));
            DescriptionAttribute descAttr = Attribute.GetCustomAttribute(field, typeof(DescriptionAttribute)) as DescriptionAttribute;
            if (descAttr == null)
            {
                return string.Empty;
            }
            return descAttr.Description;
        }

    }
}

使用方法:
新增或更新数据,我这样处理:
image

记录日志,这样处理:
image

前台解析日志:
image

image

枚举类型根据自己需要定义:

/// <summary>
        /// 操作类型
        /// </summary>
        public enum OperationType
        {
            [Description("新建资料")]
            Add = 0,
            [Description("更新资料")]
            Update = 1,
            [Description("删除资料")]
            Delete = 2,
            [Description("登录")]
            Login = 3
        }

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions