代码改变世界

c# 实体处理工具类

2016-09-14 09:46  newbirth  阅读(765)  评论(0编辑  收藏  举报
using System;
using System.Collections;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Linq;
using System.Reflection;
using System.Text;
using System.Text.RegularExpressions;
namespace HuaTong.General.Utility
{
    /// <summary>
    /// 实体处理工具类
    /// </summary>
    public static class ModelHandler
    {

        /// <summary>
        /// Determine of specified type is nullable
        /// </summary>
        public static bool IsNullable(Type t)
        {
            return !t.IsValueType || (t.IsGenericType && t.GetGenericTypeDefinition() == typeof(Nullable<>));
        }

        /// <summary>
        /// Return underlying type if type is Nullable otherwise return the type
        /// </summary>
        public static Type GetCoreType(Type t)
        {
            if (t != null && IsNullable(t))
            {
                if (!t.IsValueType)
                {
                    return t;
                }
                else
                {
                    return Nullable.GetUnderlyingType(t);
                }
            }
            else
            {
                return t;
            }
        }

        public static object Copy(this object obj)
        {
            Object targetDeepCopyObj;
            Type targetType = obj.GetType();
            //值类型  
            if (targetType.IsValueType == true)
            {
                targetDeepCopyObj = obj;
            }
            //引用类型   
            else
            {
                targetDeepCopyObj = System.Activator.CreateInstance(targetType);   //创建引用对象   
                System.Reflection.MemberInfo[] memberCollection = obj.GetType().GetMembers();

                foreach (System.Reflection.MemberInfo member in memberCollection)
                {
                    if (member.MemberType == System.Reflection.MemberTypes.Field)
                    {
                        System.Reflection.FieldInfo field = (System.Reflection.FieldInfo)member;
                        Object fieldValue = field.GetValue(obj);
                        if (fieldValue is ICloneable)
                        {
                            field.SetValue(targetDeepCopyObj, (fieldValue as ICloneable).Clone());
                        }
                        else
                        {
                            field.SetValue(targetDeepCopyObj, Copy(fieldValue));
                        }

                    }
                    else if (member.MemberType == System.Reflection.MemberTypes.Property)
                    {
                        System.Reflection.PropertyInfo myProperty = (System.Reflection.PropertyInfo)member;
                        MethodInfo info = myProperty.GetSetMethod(false);
                        if (info != null)
                        {
                            object propertyValue = myProperty.GetValue(obj, null);
                            if (propertyValue is ICloneable)
                            {
                                myProperty.SetValue(targetDeepCopyObj, (propertyValue as ICloneable).Clone(), null);
                            }
                            else
                            {
                                myProperty.SetValue(targetDeepCopyObj, Copy(propertyValue), null);
                            }
                        }

                    }
                }
            }
            return targetDeepCopyObj;
        }

        public static T CloneEntity<T>(this T entity) where T : new()
        {
            T ent = new T();
            PropertyInfo[] propertyInfoes = PropCache<T>();
            foreach (PropertyInfo propertyInfo in propertyInfoes)
            {
                if (propertyInfo.PropertyType.IsArray || (propertyInfo.PropertyType.IsClass && propertyInfo.PropertyType != typeof(string)))
                {
                    object child = propertyInfo.GetValue(entity, null);
                    if (child == null)
                        continue;
                    Type childType = child.GetType();
                    if (childType.IsGenericType)
                    {

                        Type typeDefinition = childType.GetGenericArguments()[0];
                        IList items = childType.Assembly.CreateInstance(childType.FullName) as IList;

                        PropertyInfo[] childPropertyInfoes = PropCache(typeDefinition);
                        IList lst = child as IList;
                        for (int i = 0; i < lst.Count; i++)
                        {
                            object itemEntity = null;
                            if (typeDefinition.IsClass && typeDefinition != typeof(string))
                            {
                                itemEntity = typeDefinition.Assembly.CreateInstance(typeDefinition.FullName);
                                foreach (PropertyInfo childProperty in childPropertyInfoes)
                                {
                                    childProperty.SetValue(itemEntity, childProperty.GetValue(lst[i], null), null);
                                }
                            }
                            else
                            {
                                itemEntity = lst[i];
                            }


                            items.Add(itemEntity);
                        }
                        propertyInfo.SetValue(ent, items, null);

                    }
                    continue;
                }
                propertyInfo.SetValue(ent, propertyInfo.GetValue(entity, null), null);
            }

            FieldInfo[] fieldInfoes = typeof(T).GetFields(BindingFlags.Public | BindingFlags.Instance);
            foreach (FieldInfo fieldInfo in fieldInfoes)
            {
                fieldInfo.SetValue(ent, fieldInfo.GetValue(entity));
            }

            return ent;
        }

        /// <summary>
        /// 复制实体的属性至另一个类实体的同名属性(属性不区分大小写),被复制的值必须支持隐式转换
        /// </summary>
        public static T1 CopyEntity<T1, T2>(T1 copyTo, T2 from, string replace_copy = null, string replace_from = null)
            where T1 : class, new()
            where T2 : class, new()
        {
            var prop1 = ModelHandler.PropCache<T1>();
            var prop2 = ModelHandler.PropCache<T2>();


            foreach (var p1 in prop1)
            {
                var fname = replace_copy != null ? Regex.Replace(p1.Name, replace_copy, "") : p1.Name;

                //同名属性不区分大小写
                var p2 = prop2.SingleOrDefault(
                    m => replace_from != null
                        ? StringHelper.IsEqualString(Regex.Replace(m.Name, replace_from, ""), fname)
                        : StringHelper.IsEqualString(m.Name, fname));
                if (p2 != null)
                {
                    var p2value = p2.GetValue(from, null);
                    //忽略空值
                    if (p2value != null && p2value != DBNull.Value)
                    {
                        //是否Nullable
                        if (p1.PropertyType.IsGenericType &&
                            p1.PropertyType.GetGenericTypeDefinition().Equals(typeof (Nullable<>)))
                        {
                            //Nullable数据转换
                            NullableConverter converter = new NullableConverter(p1.PropertyType);
                            p1.SetValue(copyTo, converter.ConvertFrom(p2value.ToString()), null);
                        }
                        else
                        {
                            p1.SetValue(copyTo, Convert.ChangeType(p2value, p1.PropertyType), null);
                        }
                    }
                    else if (p2.PropertyType == typeof (string))
                    {
                        //字符串添加默认值string.Empty
                        p1.SetValue(copyTo, string.Empty, null);
                    }
                }
            }
            return copyTo;
        }

        /// <summary>
        /// 复制实体集合
        /// </summary>
        public static List<T1> CopyEntityList<T1, T2>(List<T1> copyTo, List<T2> from)
            where T1 : class, new()
            where T2 : class, new()
        {
            foreach (var f in from)
            {
                var copyto = new T1();
                CopyEntity(copyto, f);
                copyTo.Add(copyto);
            }
            return copyTo;
        }


        private static object _sync = new object();
        private static Dictionary<int, PropertyInfo[]> propDictionary = new Dictionary<int, PropertyInfo[]>();

        /// <summary>
        /// 获取指定类型的PropertyInfo缓存
        /// </summary>
        public static PropertyInfo[] PropCache<T>()
        {
            return PropCache(typeof(T));
        }

        /// <summary>
        /// 获取指定类型的PropertyInfo缓存
        /// </summary>
        public static PropertyInfo[] PropCache(object obj)
        {
            return PropCache(obj.GetType());
        }

        /// <summary>
        /// 获取指定类型的PropertyInfo缓存
        /// </summary>
        public static PropertyInfo[] PropCache(Type type)
        {
            int propCode = type.GetHashCode();
            if (!propDictionary.ContainsKey(propCode))
            {
                lock (_sync)
                {
                    if (!propDictionary.ContainsKey(propCode))
                    {
                        var props = type.GetProperties(BindingFlags.Public | BindingFlags.Instance);
                        List<PropertyInfo> tmplist = new List<PropertyInfo>();
                        foreach (var prop in props)
                        {
                            if (!prop.Name.StartsWith("__"))
                            {
                                tmplist.Add(prop);
                            }
                        }
                        propDictionary.Add(propCode, tmplist.ToArray());
                    }
                }
            }

            return propDictionary[propCode];
        }
    }
}