利用反射对应数据库字段

     #region DataSet数据读取
        protected delegate P GetDataSetItemHandler<P>(DataRow row);
        internal static T GetItem(DataRow dr)
        {
            T item = new T();
            DataTableAttribute tableAttribute = DataEntity.GetTableAttribute<T>();
            if (tableAttribute != null)
            {
                for (int i = 0; i < dr.Table.Columns.Count; i++)
                {
                    string columnName = dr.Table.Columns[i].ColumnName;
                    if (dr.IsNull(i) == true || tableAttribute.DataColumnDict.Keys.Contains(columnName) == false)
                        continue;
                    DataColumnAttribute columnAttribute = tableAttribute.DataColumnDict[columnName];
                    object value = dr[i];
                    var setterMethod = columnAttribute.GetEmitSetter<T>();
                    setterMethod(item, value);
                }
            }
            return item;
        }
        /// <summary>
        /// 获取数据读取的列表
        /// </summary>
        protected List<P> GetDataSetList<P>(string sql, IDataParameter[] parameters, GetDataSetItemHandler<P> getItem)
        {
            List<P> list = null;
            DataSet ds = null;
            if (parameters != null)
                ds = DBUtility.DBHelperSQL.ExecuteDataSet(sql, parameters);
            else
                ds = DBUtility.DBHelperSQL.ExecuteDataSet(sql);
            if (ds != null && ds.Tables.Count > 0)
            {
                DataTable dt = ds.Tables[0];
                list = new List<P>(dt.Rows.Count);
                foreach (DataRow row in dt.Rows)
                {
                    P p = getItem(row);
                    if (p != null)
                        list.Add(p);
                }
                dt.Dispose();
                ds.Dispose();
            }
            return list;
        }
        /// <summary>
        /// 获取数据读取的分页列表
        /// </summary>
        protected List<P> GetDataSetPageList<P>(string sql, IDataParameter[] parameters, GetDataSetItemHandler<P> getItem,int pageIndex,int pageSize, out int recordCount)
        {
            //分页SQL
            //sql = RebuildPageSql(sql, pageIndex, pageSize, ref parameters);

            recordCount = 0;
            int endIndex = pageIndex * pageSize;
            int startIndex = endIndex - pageSize + 1;
            List<P> list = null;
            DataSet ds = null;
            if (parameters != null)
                ds = DBUtility.DBHelperSQL.ExecuteDataSet(sql, parameters);
            else
                ds = DBUtility.DBHelperSQL.ExecuteDataSet(sql);
            if (ds != null && ds.Tables.Count > 0)
            {
                DataTable dataTable = ds.Tables[0];
                //DataTable recordCountTable = ds.Tables[1];
                list = new List<P>(dataTable.Rows.Count);
                foreach (DataRow row in dataTable.Rows)
                {
                    recordCount++;
                    if (startIndex <= recordCount && recordCount <= endIndex)
                    {
                        P p = getItem(row);
                        if (p != null)
                            list.Add(p);
                    }
                }
                //if (recordCountTable.Rows.Count > 0)
                //    recordCount = (int)recordCountTable.Rows[0]["record_count"];
                //recordCountTable.Dispose();
                dataTable.Dispose();
                ds.Dispose();
            }
            return list;
        }


        /// <summary>
        /// 获取存储过程数据读取的列表
       /// </summary>
        protected List<P> GetDataSetProcedureList<P>(string storedProcName, IDataParameter[] parameters, GetDataSetItemHandler<P> getItem)
        {
            List<P> list = null;
            DataSet ds = DBUtility.DBHelperSQL.ExecuteDataSetProcedure(storedProcName, parameters);
            if (ds != null && ds.Tables.Count > 0)
            {
                DataTable dt = ds.Tables[0];
                list = new List<P>(dt.Rows.Count);
                foreach (DataRow row in dt.Rows)
                {
                    P p = getItem(row);
                    if (p != null)
                        list.Add(p);
                }
                dt.Dispose();
                ds.Dispose();
            }
            return list;

        }
        /// <summary>
        /// 获取数据读取的单项信息
        /// </summary>
        protected P GetDataSetItem<P>(string sql, IDataParameter[] parameters, GetDataSetItemHandler<P> getItem)
        {
            P item = default(P);
            DataSet ds = null;
            if (parameters != null)
                ds = DBUtility.DBHelperSQL.ExecuteDataSet(sql, parameters);
            else
                ds = DBUtility.DBHelperSQL.ExecuteDataSet(sql);
            if (ds != null && ds.Tables.Count > 0)
            {
                DataTable dt = ds.Tables[0];
                foreach (DataRow row in dt.Rows)
                {
                    item = getItem(row);
                    break;
                }
                dt.Dispose();
                ds.Dispose();
            }
            return item;
        }
        /// <summary>
        /// 获取数据读取的单项信息
        /// </summary>
        protected P GetDataSetProcedureItem<P>(string storedProcName, IDataParameter[] parameters, GetDataSetItemHandler<P> getItem)
        {
            P item = default(P);
            DataSet ds = DBUtility.DBHelperSQL.ExecuteDataSetProcedure(storedProcName, parameters);
            if (ds != null && ds.Tables.Count > 0)
            {
                DataTable dt = ds.Tables[0];
                foreach (DataRow row in dt.Rows)
                {
                    item = getItem(row);
                    break;
                }
                dt.Dispose();
                ds.Dispose();
            }
            return item;
        }

        #endregion

ColumnAttribute

  public class DataColumnAttribute : Attribute
    {
        private string column_name;
        private System.Data.DbType column_type = DbType.String;
        private int length = 0;
        private bool identity_id;
        private bool ignore;
        private string description;
        private string property_name;
        public DataColumnAttribute()
        {

        }
        public DataColumnAttribute(string columnName)
        {
            this.column_name = columnName;
        }
        public string ColumnName
        {
            get { return column_name; }
            set { column_name = value; }
        }
        public DbType ColumnType
        {
            get { return column_type; }
            set
            {
                column_type = value;
                if (length == 0)
                {
                    if (column_type == DbType.Decimal)
                    {
                        length = 22;
                    }
                    else if (column_type == DbType.String)
                    {
                        length = 32;
                    }
                    else
                        length = 0;
                }
            }
        }
        public bool IdentityID
        {
            get { return identity_id; }
            set {
                identity_id = value;
                if (identity_id)
                {
                    column_type = DbType.Decimal;
                    length = 22;
                }
            }
        }
        public string Description
        {
            get { return description; }
            set { description = value; }
        }
        public bool Ignore
        {
            get { return ignore; }
            set { ignore = value; }
        }
        public int Length
        {
            get { return length; }
            set { length = value; }
        }
        public string PropertyName
        {
            get { return property_name; }
            set { property_name = value; }
        }
        private object emit_setter = null;
        public void SetEmitSetter<T>(Action<T, object> action)
        {
            emit_setter = action;
        }
        public Action<T, object> GetEmitSetter<T>()
        {
            return emit_setter as Action<T, object>;
        }
    }

DataTableAttribute 

 public class DataTableAttribute : Attribute
    {
        private string table_name;
        private string identityid_name;
        private string description;
        private IDictionary<string, DataColumnAttribute> dataColumnDict;
        public DataTableAttribute()
        {
            this.dataColumnDict = new Dictionary<string, DataColumnAttribute>(50);
        }
        public DataTableAttribute(string tableName) : this()
        {
            this.table_name = tableName;
        }
        public string TableName
        {
            get { return table_name; }
            set { table_name = value; }
        }
        public string IdentityIDName
        {
            get { return identityid_name; }
            set { identityid_name = value; }
        }
        public string Description
        {
            get { return description; }
            set { description = value; }
        }
        public IDictionary<string, DataColumnAttribute> DataColumnDict
        {
            get { return dataColumnDict; }
            set { dataColumnDict = value; }
        }

    }
   public class DataEntity
    {
        static readonly object padlock = new object();
        private static Dictionary<string, DataTableAttribute> table_dict = new Dictionary<string, DataTableAttribute>(100);
        public static DataTableAttribute GetTableAttribute<T>()
        {
            DataTableAttribute table_attribute = null;
            string class_name = typeof(T).ToString();
            if (table_dict.ContainsKey(class_name))
            {
                table_attribute = table_dict[class_name];
            }
            if (table_attribute == null)
            {
                lock (padlock)
                {
                    if (table_attribute == null)
                    {
                        //通过反射获取数据表特性
                        object[] attributes = typeof(T).GetCustomAttributes(typeof(DataTableAttribute), false);
                        if (attributes != null && attributes.Length > 0)
                        {
                            table_attribute = (DataTableAttribute)attributes[0];
                            //通过反射获取数据列特性
                            PropertyInfo[] properties = typeof(T).GetProperties();
                            foreach (PropertyInfo propertie in properties)
                            {
                                object[] pro_attributes = propertie.GetCustomAttributes(typeof(DataColumnAttribute), true);
                                if (pro_attributes != null && pro_attributes.Length > 0)
                                {

                                    DataColumnAttribute column_attribute = (DataColumnAttribute)pro_attributes[0];
                                    //默认的唯一ID
                                    if (column_attribute.IdentityID == true)
                                    {
                                        table_attribute.IdentityIDName = column_attribute.ColumnName;
                                    }
                                    column_attribute.PropertyName = propertie.Name;
                                    column_attribute.SetEmitSetter(EmitSetter<T>(propertie.Name));
                                    #region 列数据类型
                                    if (column_attribute.ColumnType != DbType.AnsiString)
                                    {
                                        if (propertie.PropertyType == typeof(decimal))
                                        {
                                            column_attribute.ColumnType = DbType.Decimal;
                                        }
                                        else if (propertie.PropertyType == typeof(short))
                                        {
                                            column_attribute.ColumnType = DbType.Int16;
                                        }
                                        else if (propertie.PropertyType == typeof(int))
                                        {
                                            column_attribute.ColumnType = DbType.Int32;
                                        }
                                        else if (propertie.PropertyType == typeof(long))
                                        {
                                            column_attribute.ColumnType = DbType.Int64;
                                        }
                                        else if (propertie.PropertyType == typeof(bool))
                                        {
                                            column_attribute.ColumnType = DbType.Boolean;
                                        }
                                        else if (propertie.PropertyType == typeof(DateTime) || propertie.PropertyType == typeof(DateTime?))
                                        {
                                            column_attribute.ColumnType = DbType.DateTime;
                                        }
                                        else if (propertie.PropertyType == typeof(double) || propertie.PropertyType == typeof(float))
                                        {
                                            column_attribute.ColumnType = DbType.Double;
                                        }
                                        else
                                        {
                                            column_attribute.ColumnType = DbType.String;
                                        }
                                    }
                                    #endregion
                                    table_attribute.DataColumnDict.Add(column_attribute.ColumnName, column_attribute);


                                }
                            }
                            if (table_dict.ContainsKey(class_name))
                                table_dict[class_name] = table_attribute;
                            else
                                table_dict.Add(class_name, table_attribute);
                        }
                    }
                }
            }
            return table_attribute;
        }
        /// <summary>
        /// 反射获取对象的属性值
        /// </summary>
        /// <param name="obj"></param>
        /// <param name="propertyName"></param>
        /// <returns></returns>
        public static object ReflectGetter(object obj, string propertyName)
        {
            var type = obj.GetType();
            PropertyInfo propertyInfo = type.GetProperty(propertyName);
            var propertyValue = propertyInfo.GetValue(obj, null);
            return propertyValue;
        }
        public static DataColumnAttribute ExpresionGetter<T>(Expression<Func<T, object>> expr)
        {
            DataColumnAttribute column_attribute = null;
            object[] attributes = null;
            if (expr.Body is UnaryExpression)
            {
                attributes = ((MemberExpression)((UnaryExpression)expr.Body).Operand).Member.GetCustomAttributes(typeof(DataColumnAttribute), true);
            }
            else if (expr.Body is MemberExpression)
            {
                attributes = ((MemberExpression)expr.Body).Member.GetCustomAttributes(typeof(DataColumnAttribute), true);
            }
            else if (expr.Body is ParameterExpression)
            {
                attributes = ((ParameterExpression)expr.Body).Type.GetCustomAttributes(typeof(DataColumnAttribute), true);
            }
            if (attributes != null && attributes.Length > 0)
            {
                string column_name = (attributes[0] as DataColumnAttribute).ColumnName;
                if (column_name == "module_content")
                {

                }
                DataTableAttribute TableAttribute = DataEntity.GetTableAttribute<T>();
                if (TableAttribute != null && TableAttribute.DataColumnDict.ContainsKey(column_name))
                    column_attribute = TableAttribute.DataColumnDict[column_name];
            }
            return column_attribute;
        }
        /// <summary>
        /// 表达式设置对象的属性值
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="propertyName"></param>
        /// <returns></returns>
        public static Action<T, object> ExpresionSetter<T>(string propertyName)
        {
            var type = typeof(T);
            var property = type.GetProperty(propertyName);


            var objectParameterExpression = Expression.Parameter(typeof(object), "obj");
            var objectUnaryExpression = Expression.Convert(objectParameterExpression, type);


            var valueParameterExpression = Expression.Parameter(typeof(object), "val");
            var valueUnaryExpression = Expression.Convert(valueParameterExpression, property.PropertyType);


            //// 调用给属性赋值的方法
            var body = Expression.Call(objectUnaryExpression, property.GetSetMethod(), valueUnaryExpression);
            var expression = Expression.Lambda<Action<T, object>>(body, objectParameterExpression, valueParameterExpression);


            return expression.Compile();
        }

        /// <summary>
        /// 反射设置对象的属性值
        /// </summary>
        /// <param name="obj"></param>
        /// <param name="propertyName"></param>
        /// <param name="propertyValue"></param>
        public static void ReflectSetter(object obj, string propertyName, object propertyValue)
        {
            var type = obj.GetType();
            var propertyInfo = type.GetProperty(propertyName);
            propertyInfo.SetValue(obj, propertyValue, null);
        }

        /// <summary>
        /// Emit设置对象的属性值
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <returns></returns>
        public static Action<T, object> EmitSetter<T>(string propertyName)
        {
            var type = typeof(T);
            var dynamicMethod = new DynamicMethod("EmitCallable", null, new[] { type, typeof(object) }, type.Module);
            var iLGenerator = dynamicMethod.GetILGenerator();

            var callMethod = type.GetMethod("set_" + propertyName, BindingFlags.Instance | BindingFlags.IgnoreCase | BindingFlags.Public);
            var parameterInfo = callMethod.GetParameters()[0];
            var local = iLGenerator.DeclareLocal(parameterInfo.ParameterType, true);

            iLGenerator.Emit(OpCodes.Ldarg_1);
            if (parameterInfo.ParameterType.IsValueType)
            {
                // 如果是值类型,拆箱
                iLGenerator.Emit(OpCodes.Unbox_Any, parameterInfo.ParameterType);
            }
            else
            {
                // 如果是引用类型,转换
                iLGenerator.Emit(OpCodes.Castclass, parameterInfo.ParameterType);
            }

            iLGenerator.Emit(OpCodes.Stloc, local);
            iLGenerator.Emit(OpCodes.Ldarg_0);
            iLGenerator.Emit(OpCodes.Ldloc, local);


            iLGenerator.EmitCall(OpCodes.Callvirt, callMethod, null);
            iLGenerator.Emit(OpCodes.Ret);


            return dynamicMethod.CreateDelegate(typeof(Action<T, object>)) as Action<T, object>;
        }
    }
111111
原文地址:https://www.cnblogs.com/whl4835349/p/10412990.html