关于C#反射操作类

c#利用反射+特性实现简单的实体映射数据库操作类(表与类的映射)

开始之前首先需要了解 特性Attribute; 说穿了特性也就是一些声明信息;我们在运行的时候可以用反射获取这些声明;

所想我们试想下;我们新建一个类用来存放数据库表中的信息; 那我们是不是需要在该类中有专门存放该表字段信息的类的字段呢?(这里说的是存放表中的全部字段信息)

  在想想下,描述一个数据库字段需要哪些信息; 二类中字段可以满足哪些信息吗!  所以我们需要对该字段进行描述 ,比如说字段名称呀,字段数据类型呀,字段数据类型长度呀,还有有是否为主键呀?

 我也是初学者 我这里只是说最基础的
建立特性类;

using  System;
using  System.Collections.Generic;
using  System.Linq;
using  System.Text;
using  System.Data;

namespace  DataTransfer
{
    [AttributeUsage(AttributeTargets.Property,AllowMultiple
= false ,Inherited = false )]
     
public   class  FieldAttribute:Attribute
    {
        
private   string  _Fields;
        
///   <summary>
        
///  字段名称
        
///   </summary>
         public   string  Fields
        {
          
get  {  return  _Fields; }

        }

        
private   DbType _Dbtype;
        
///   <summary>
        
///  字段类型
        
///   </summary>
         public  DbType Dbtype
        {
          
get  {  return  _Dbtype; }

        }

        
private   int  _ValueLength;
        
///   <summary>
        
///  字段值长度
        
///   </summary>
         public   int  ValueLength
        {
          
get  {  return  _ValueLength; }
        
        }
        
///   <summary>
        
///  构造函数
        
///   </summary>
        
///   <param name="fields">  字段名 </param>
        
///   <param name="types">  字段类型 </param>
        
///   <param name="i">  字段值长度 </param>
          public  FieldAttribute( string  fields,DbType types,  int  i)
        {
            
             _Fields
= fields;
             _Dbtype
= types;
           
                _ValueLength
= i;
        }
    }
}

using  System;
using  System.Collections.Generic;
using  System.Linq;
using  System.Text;

namespace  DataTransfer
{
     [AttributeUsage(AttributeTargets.Class,AllowMultiple
= false ,Inherited = false )]
     
public   class  TableAttribute:Attribute
    {
        
private   string  _TableName;
        
///   <summary>
        
///  映射的表名
        
///   </summary>
         public   string  TableName
        {
            
get  {  return  _TableName; }
        }
         
///   <summary>
         
///  定位函数映射表名;
         
///   </summary>
         
///   <param name="table"></param>
          public  TableAttribute( string  table)
         {
             _TableName 
=  table;
         }

    }
}

 

这里是建立的2个特性类; 建立与表映射的类TableAttribute 外加与字段映射的类 FieldAttribute;

建立联系的类

using  System;
using  System.Collections.Generic;
using  System.Linq;
using  System.Text;
using  System.Data;
namespace  DataTransfer
{

    [Table(
" Consumers " )] //   这里[Table("Consumers")]  或者  [TableAttribute("Consumers")] 是一样的效果
      public   class  UserInf
    {
        
private   string  _UserID;
         
///   <summary>
         
///  登陆ID
         
///   </summary>
       [Field( " ConsumerID " ,DbType.String, 12 )]
        
public   string  U_UserID
        {
            
get  {  return  _UserID; }
            
set  { _UserID  =  value; }
        }
        
        
private   string  _Psw;
         
///   <summary>
         
///  登陆密码
         
///   </summary>
        [Field( " ConsumerPwd " ,DbType.String, 12 )]
        
public   string  U_Psw
        {
            
get  {  return  _Psw; }
            
set  { _Psw  =  value; }
        }
       
        
private   string  _UserName;
         
///   <summary>
         
///  用户别称
         
///   </summary>
       [Field( " ConsumerName " ,DbType.String, 50 )]
        
public   string  U_UserName
        {
            
get  {  return  _UserName; }
            
set  { _UserName  =  value; }
        }

        
private   string  _City;
         
///   <summary>
         
///  所住城市
         
///   </summary>
        [Field( " UserCity " ,DbType.String, 50 )]
        
public   string  U_City
        {
            
get  {  return  _City; }
            
set  { _City  =  value; }
        }

        
private   int  _Popedom;
         
///   <summary>
         
///  权限
         
///   </summary>
       [Field( " popedom " , DbType.Int32,  0 )]
        
public   int  U_Popedom
        {
            
get  {  return  _Popedom; }
            
set  { _Popedom  =  value; }
        }

        
private  DateTime _AddDataTime;
         
///   <summary>
         
///  注册时间
         
///   </summary>
      [Field( " addDataTime " ,DbType.Date, 0 )]
        
public  DateTime U_AddDataTime
        {
            
get  {  return  _AddDataTime; }
            
set  { _AddDataTime  =  value; }
        }

        
private   int  _Sex;
         
///   <summary>
         
///  性别
         
///   </summary>
       [Field( " Sex " ,DbType.Int32, 0 )]
        
public   int  U_Sex
        {
            
get  {  return  _Sex; }
            
set  { _Sex  =  value; }
        }
       
        
private   int  _BirthTime;
         
///   <summary>
         
///  出身日期;
         
///   </summary>
       [Field( " BirthTime " , DbType.String,  9 )]
        
public   int  U_BirthTime
        {
            
get  {  return  _BirthTime; }
            
set  { _BirthTime  =  value; }
        }

    }
}

 

在aspx页面中
  UserInf userss  =   new  UserInf();

        userss.U_UserID 
=   " aw12311 " ;
        userss.U_Psw 
=   " 123 " ;
        userss.U_UserName 
=   " aw " ;
        userss.U_City 
=   " 武汉 " ;
        userss.U_Popedom 
=   1 ;
        userss.U_Sex 
=   1 ;
        userss.U_BirthTime 
=   19900114 ;
        userss.U_AddDataTime 
=  DateTime.Now;

/// 这里先让你查看字段描述;

查看表的特性;

  Type userAttu 
=  userss.GetType();
        TableAttribute tables 
=  (TableAttribute)userAttu.GetCustomAttributes( false )[ 0 ]; // 这里我在TableAttribute个类中写的是不容许多个描述,所以只有一个实例;
        Response.Write(tables.TableName);

// 查看类中字段的描述

PropertyInfo[] info 
=  userAttu.GetProperties();

       
foreach  (PropertyInfo prs  in  info)
       {
           Response.Write(
" --------------------------------</br> " );
           
object [] attu  =  prs.GetCustomAttributes( false );
           
object  obj  =  prs.GetGetMethod().Invoke(userss, null ); // 取出当前描述字段的值
           Response.Write(prs.Name  + " | " +  obj  + " </br> " ); // 这里显示类中字段的名称 与值


             
foreach (Attribute abute  in  attu )
             {

                 
if  (abute  is  FieldAttribute)
                 {
                     FieldAttribute column 
=  abute  as  FieldAttribute;
                     Response.Write(column.Fields 
+ " </br> " );
                     Response.Write(column.Dbtype 
+   " </br> " );
                     Response.Write(column.ValueLength 
+   " </br> " );
                 }
         
             }

       }

接着在 c# 中   传递帮他了的类拼接处查询字符串;

using  System;
using  System.Collections.Generic;
using  System.Linq;
using  System.Text;
using  System.Data;
using  System.Reflection;
namespace  DataTransfer
{
    
public   class  DateIsTableAttribute < T >
    {


        
public   string  insertDate(T types)
        {
            
string  cmdtxt  =   " insert into  " ;
            
string  cmdparVar  =   null ;
            Type userAttu 
=  types.GetType();
            TableAttribute  tables 
=  (TableAttribute )userAttu.GetCustomAttributes( false )[ 0 ];
            cmdtxt 
+=  tables.TableName  +   " ( " ;
            PropertyInfo[] info 
=  userAttu.GetProperties();

            
foreach  (PropertyInfo prs  in  info)
            {
                
object [] attu  =  prs.GetCustomAttributes( false );

                
foreach  (Attribute abute  in  attu)
                {
                    
if  (abute  is  FieldAttribute)
                    {
                        FieldAttribute midle 
=  abute  as  FieldAttribute;
                         cmdtxt 
+=   midle.Fields  +   " , " ;
                         
object  obj  =  prs.GetGetMethod().Invoke(types, null );
                        
if  (midle.Dbtype  ==  DbType.Int32)
                            cmdparVar 
+=   obj  +   " , " ;
                        
else
                            cmdparVar
+= " ' " + obj  + " ', " ;
                       
                    }
                }
                
            }

            cmdparVar 
=  cmdparVar.Substring( 0 , cmdparVar.Length  -   1 );
            cmdtxt 
=  cmdtxt.Substring( 0 , cmdtxt.Length  -   1 +   " ) " ;

            cmdtxt 
+=   " values( "   +  cmdparVar  +   " ) " ;
            
return  cmdtxt;
        }
    }
}

然后再aspx 中的页面调用该方法 

  DateIsTableAttribute<UserInf> t = new DateIsTableAttribute<UserInf>();

///此处的userss 是上面实例化并赋值的userss;
       Response.Write(" </br>" + t.insertDate(userss));

//这样你就会看到拼接完成的  插入字符串;

这只是思路 当我们字段插入字符串后那对数据库的插入我们就应该是小意思了吧! 同理我们可以做出响应的修改删除;

当我们需要插入并一张表的时候,或者修改等 , 那我们只需要新建一个加特征的与我们需要映射的表就好了其他都不需要改了;当我们吧那些插入 修改 删除 都包装在一起 , 那我们就可以实现自动化了 ,我们唯一需要做的就是怎样去建立类与数据库的映射就好了!;


另外一个通用的操作类:
///   <summary>
  
///  获取用户数据库分页数据
  
///   </summary>
  
///   <param name="TableName"></param>
  
///   <param name="PageSize"></param>
  
///   <param name="PageIndex"></param>
  
///   <param name="SqlWhere"></param>
  
///   <returns></returns>
   public  DataSet GetList( string  TableName, int  PageSize, int  PageIndex, string  SqlWhere)
  {
      
try
      {
          Assembly a 
=  ReflectionUtil.LoadAssembly(Globals.UserDATA_Assembly  +   " .BLL " ); // 创建一个程序集
          Type t  =  ReflectionUtil.GetType(a, Globals.UserDATA_Assembly  +   " .BLL. "   +  TableName  +   " BLL " );
          
object  o  =  ReflectionUtil.CreateInstance(t,  null );
          Type[] types 
=   new  Type[ 3 ];
          types[
0 =  Type.GetType( " System.Int32 " );
          types[
1 =  Type.GetType( " System.Int32 " );
          types[
2 =  Type.GetType( " System.String " );
          MethodInfo mi 
=  t.GetMethod( " GetList " , types);
          Object[] obj 
=   new  Object[ 3 ];
          obj[
0 =  PageSize;
          obj[
1 =  PageIndex;
          obj[
2 =  SqlWhere;
          DataSet ds 
=  (DataSet)mi.Invoke(o, obj);
          
return  ds;
      }
      
catch
      {
          
return   null ;
      }
  }
下面是类:
using  System;
using  System.Collections.Generic;
using  System.Text;
using  System.Reflection;
using  System.ComponentModel;

namespace  XINLG.Labs.Utils
{
    
///   <summary>
    
///  反射操作类
    
///   </summary>     
     public   class  ReflectionUtil
    {
        
#region  加载程序集
        
///   <summary>
        
///  加载程序集
        
///   </summary>
        
///   <param name="assemblyName"> 程序集名称,不要加上程序集的后缀,如.dll </param>         
         public   static  Assembly LoadAssembly(  string  assemblyName)
        {
            
try
            {
                
return  Assembly.Load(assemblyName);
            }
            
catch  ( Exception ex )
            {
                
string  errMsg  =  ex.Message;
                
return   null ;
            }
        }
        
#endregion

        
#region  获取程序集中的类型
        
///   <summary>
        
///  获取本地程序集中的类型
        
///   </summary>
        
///   <param name="typeName"> 类型名称,范例格式:"命名空间.类名",类型名称必须在本地程序集中 </param>         
         public   static  Type GetType(  string  typeName )
        {
            
try
            {
                
return  Type.GetType( typeName );
            }
            
catch  ( Exception ex )
            {
                
string  errMsg  =  ex.Message;
                
return   null ;
            }
        }

        
///   <summary>
        
///  获取指定程序集中的类型
        
///   </summary>
        
///   <param name="assembly"> 指定的程序集 </param>
        
///   <param name="typeName"> 类型名称,范例格式:"命名空间.类名",类型名称必须在assembly程序集中 </param>
        
///   <returns></returns>
         public   static  Type GetType( Assembly assembly ,  string  typeName )
        {
            
try
            {
                
return  assembly.GetType( typeName );
            }
            
catch  ( Exception ex )
            {
                
string  errMsg  =  ex.Message;
                
return   null ;
            }
        }
        
#endregion

        
#region  动态创建对象实例
        
///   <summary>
        
///  创建类型的实例
        
///   </summary>
        
///   <param name="type"> 类型 </param>
        
///   <param name="parameters"> 传递给构造函数的参数 </param>         
         public   static   object  CreateInstance( Type type, params   object [] parameters )
        {
            
return  Activator.CreateInstance( type, parameters );
        }

        
///   <summary>
        
///  创建类的实例
        
///   </summary>
        
///   <param name="className"> 类名,格式:"命名空间.类名" </param>
        
///   <param name="parameters"> 传递给构造函数的参数 </param>         
         public   static   object  CreateInstance(  string  className, params   object [] parameters )
        {
            
try
            {
                
// 获取类型
                Type type  =  GetType( className );

                
// 类型为空则返回
                 if  ( type  ==   null  )
                {
                    
return   null ;
                }

                
return  CreateInstance( type, parameters );
            }
            
catch  ( Exception ex )
            {
                
string  errMsg  =  ex.Message;
                
return   null ;
            }
        }       

        
#endregion


        
#region  获取类的命名空间
        
///   <summary>
        
///  获取类的命名空间
        
///   </summary>
        
///   <typeparam name="T"> 类名或接口名 </typeparam>         
         public   static   string  GetNamespace < T > ()
        {   
            
return   typeof ( T ).Namespace;
        }
        
#endregion

        
#region  设置成员的值

        
#region  设置属性值
        
///   <summary>
        
///  将值装载到目标对象的指定属性中
        
///   </summary>
        
///   <param name="target"> 要装载数据的目标对象 </param>
        
///   <param name="propertyName"> 目标对象的属性名 </param>
        
///   <param name="value"> 要装载的值 </param>
         public   static   void  SetPropertyValue(  object  target,  string  propertyName,  object  value )
        {
            PropertyInfo propertyInfo 
=  target.GetType().GetProperty( propertyName, BindingFlags.Public  |  BindingFlags.Instance  |  BindingFlags.FlattenHierarchy );
            SetValue( target, propertyInfo, value );
        }
        
#endregion

        
#region  设置成员的值
        
///   <summary>
        
///  设置成员的值
        
///   </summary>
        
///   <param name="target"> 要装载数据的目标对象 </param>
        
///   <param name="memberInfo"> 目标对象的成员 </param>
        
///   <param name="value"> 要装载的值 </param>
         private   static   void  SetValue(  object  target, MemberInfo memberInfo,  object  value )
        {
            
if  ( value  !=   null  )
            {
                
// 获取成员类型
                Type pType;
                
if  ( memberInfo.MemberType  ==  MemberTypes.Property )
                    pType 
=  ( (PropertyInfo)memberInfo ).PropertyType;
                
else
                    pType 
=  ( (FieldInfo)memberInfo ).FieldType;

                
// 获取值的类型
                Type vType  =  GetPropertyType( value.GetType() );

                
// 强制将值转换为属性类型
                value  =  CoerceValue( pType, vType, value );
            }
            
if  ( memberInfo.MemberType  ==  MemberTypes.Property )
                ( (PropertyInfo)memberInfo ).SetValue( target, value, 
null  );
            
else
                ( (FieldInfo)memberInfo ).SetValue( target, value );
        } 
        
#endregion

        
#region  强制将值转换为指定类型
        
///   <summary>
        
///  强制将值转换为指定类型
        
///   </summary>
        
///   <param name="propertyType"> 目标类型 </param>
        
///   <param name="valueType"> 值的类型 </param>
        
///   <param name="value"> </param>
         private   static   object  CoerceValue( Type propertyType, Type valueType,  object  value )
        {
            
// 如果值的类型与目标类型相同则直接返回,否则进行转换
             if  ( propertyType.Equals( valueType ) )
            {                
                
return  value;
            }
            
else
            {
                
if  ( propertyType.IsGenericType )
                {
                    
if  ( propertyType.GetGenericTypeDefinition()  ==   typeof ( Nullable <>  ) )
                    {
                        
if  ( value  ==   null  )
                            
return   null ;
                        
else   if  ( valueType.Equals(  typeof string  ) )  &&  ( string )value  ==   string .Empty )
                            
return   null ;
                    }
                    propertyType 
=  GetPropertyType( propertyType );
                }

                
if  ( propertyType.IsEnum  &&  valueType.Equals(  typeof string  ) ) )
                    
return  Enum.Parse( propertyType, value.ToString() );

                
if  ( propertyType.IsPrimitive  &&  valueType.Equals(  typeof string  ) )  &&   string .IsNullOrEmpty( ( string )value ) )
                    value 
=   0 ;

                
try
                {
                    
return  Convert.ChangeType( value, GetPropertyType( propertyType ) );
                }
                
catch ( Exception ex )
                {
                    TypeConverter cnv 
=  TypeDescriptor.GetConverter( GetPropertyType( propertyType ) );
                    
if  ( cnv  !=   null   &&  cnv.CanConvertFrom( value.GetType() ) )
                        
return  cnv.ConvertFrom( value );
                    
else
                        
throw  ex;
                }
            }
        }
        
#endregion

        
#region  获取类型,如果类型为Nullable<>,则返回Nullable<>的基础类型
        
///   <summary>
        
///  获取类型,如果类型为Nullable(of T),则返回Nullable(of T)的基础类型
        
///   </summary>
        
///   <param name="propertyType"> 需要转换的类型 </param>
         private   static  Type GetPropertyType( Type propertyType )
        {
            Type type 
=  propertyType;
            
if  ( type.IsGenericType  &&  ( type.GetGenericTypeDefinition()  ==   typeof ( Nullable <>  ) ) )
                
return  Nullable.GetUnderlyingType( type );
            
return  type;
        }
        
#endregion

        
#endregion
    }
}
 url: http://greatverve.cnblogs.com/archive/2011/06/30/csharp-reflection.html
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值