-
-
Notifications
You must be signed in to change notification settings - Fork 1.4k
Open
Labels
Description
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;
}
}
}
枚举类型根据自己需要定义:
/// <summary>
/// 操作类型
/// </summary>
public enum OperationType
{
[Description("新建资料")]
Add = 0,
[Description("更新资料")]
Update = 1,
[Description("删除资料")]
Delete = 2,
[Description("登录")]
Login = 3
}



