Skip to content

加了一个ModelMapHelper类 #341

@xcanel

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
        }

Metadata

Metadata

Assignees

No one assigned

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions