VB.net 2010 视频教程 VB.net 2010 视频教程 python基础视频教程
SQL Server 2008 视频教程 c#入门经典教程 Visual Basic从门到精通视频教程
当前位置:
首页 > 编程开发 > Objective-C编程 >
  • 反射学习系列2 特性Attribute

制作者:剑锋冷月 单位:无忧统计网,www.51stat.net
  本文示例源代码或素材下载
  先看一个简单的例子
[Table(Name="dbo.[User]")]
public partial class User
{
  当C#编译器发现这个属性有一个特性Table时,首先会把字符串Attribute添加到这个名称的后面,形成一个组合名称TableAttribute,然后在其搜索路径的所有命名空间中搜索有相同类名的类。但要注意,如果该特性名结尾是Attribute,编译器就不会把该字符串加到组合名称中。所有的特性都是从System.Attribute类型上面派生的。
  接着我们来看一下Table特性的定制格式
[AttributeUsageAttribute(AttributeTargets.Class, Inherited=true,AllowMultiple=false)]
public class TalbeAttribute:Attribute
{
  在定义类型时使用System.AttributeUsage特性来表明这个自定义特性的使用范围,这里使用了Class样式,表示TableAttribute特性只能用在其它的Class类型前面,若放置在Interface或Struct类型前面,或者放在对象成员的前面则会出现编译错误。这里还是用语句 AllowMultiple=false 语句来表明对于一个类型,该特性只能用一次,若一个Class类型前面出现多个TableAttribute,则会出现编译错误。若设置AllowMultiple=true,则该特性可以多次定义,也就是一个Class类型前面可以出现多个相同类型的特性。不过这里我们假设一个对象只能映射到一个数据表上,没有多重映射,因此就指明对同一个类型该特性不能多次使用。Inherited参数设定为true,就表示应用到类或接口上的特性也可以自动应用到所派生的类或接口上。
  我们再看一下定制TalbeAttribute特性的完整例子:
[AttributeUsageAttribute(AttributeTargets.Class, Inherited = false, AllowMultiple = false)]
  public class TableAttribute : Attribute
  {
    //保存表名的字段
    private string _tableName;
  
    public TableAttribute()
    {
    }
  
    public TableAttribute(string tableName)
    {
      this._tableName = tableName;
    }
  
    /// <summary>
    /// 映射的表名(表的全名:模式名.表名)
    /// </summary>
    public string TableName
    {
      set
      {
        this._tableName = value;
      }
      get
      {
        return this._tableName;
      }
    }
  }
  特性也是一个Class类型,可以有多个构造函数,就像C#的new语句一样,我们向类型附加特性时可以使用不同的初始化参数来指明使用特性的那个构造函数。我们附加特性时还可以使用“属性名=属性值”的方法来直接指明特性的属性值。该特性中定义了一个TableName属性,该属性就是被修饰的对象所映射的数据库表的名称。
  下面我们举一个使用特性来进行O/RMapping的例子,也就是将对象转化成Sql语句
  用户类:
  User类
  [Table("User")]
  public class User
  {
    [Colum("userID", DbType = DbType.Int32)]
    public int UserID { get; set; }
    [Colum("UserName", DbType = DbType.String)]
    public string UserName { get; set; }
  }
  表特性
[AttributeUsageAttribute(AttributeTargets.Class, Inherited = false, AllowMultiple = false)]
  public class TableAttribute : Attribute
  {
    //保存表名的字段
    private string _tableName;
  
    public TableAttribute()
    {
    }
  
    public TableAttribute(string tableName)
    {
      this._tableName = tableName;
    }
  
    /// <summary>
    /// 映射的表名(表的全名:模式名.表名)
    /// </summary>
    public string TableName
    {
      set
      {
        this._tableName = value;
      }
      get
      {
        return this._tableName;
      }
    }
  }
  列特性:
[AttributeUsageAttribute(AttributeTargets.Property, Inherited = false, AllowMultiple = false)]
  public class ColumAttribute : Attribute
  {
    private string _columName;
  
    private DbType _dbType ;
  
    public ColumAttribute()
    {
    }
  
    public ColumAttribute(string columName)
      : this()
    {
      this._columName = columName;
    }
  
    public ColumAttribute(string columName, DbType dbType)
      : this(columName)
    {
      this._dbType = dbType;
    }
  
    //列名
    public virtual string ColumName
    {
      set
      {
        this._columName = value;
      }
      get
      {
        return this._columName;
      }
    }
  
    //描述一些特殊的数据库类型
    public DbType DbType
    {
      get { return _dbType; }
      set { _dbType = value; }
    }
  
  }
  ORMHelp
public class ORMHelp
  {
    public void Insert(object table)
    {
      Type type = table.GetType();
      //定义一个字典来存放表中字段和值的对应序列
      Dictionary<string, string> columValue = new Dictionary<string, string>();
      StringBuilder SqlStr=new StringBuilder();
      SqlStr.Append("insert into ");
      //得到表名子
      TableAttribute temp = (TableAttribute)type.GetCustomAttributes(false).First();
      SqlStr.Append(temp.TableName);
      SqlStr.Append("(");
      PropertyInfo[] Propertys=type.GetProperties();
      foreach (var item in Propertys)
      {
        object[] attributes = item.GetCustomAttributes(false);
        foreach (var item1 in attributes)
        {
          //获得相应属性的值
          string value= table.GetType().InvokeMember(item.Name, System.Reflection.BindingFlags.GetProperty, null, table, null).ToString();
          ColumAttribute colum = item1 as ColumAttribute;
          if (colum != null)
          {
            columValue.Add(colum.ColumName,value);
          }
        }
      }
      //拼插入操作字符串
      foreach (var item in columValue)
      {
        SqlStr.Append(item.Key);
        SqlStr.Append(",");
  
      }
      SqlStr.Remove(SqlStr.Length-1, 1);
      SqlStr.Append(") values('");
      foreach (var item in columValue)
      {
        SqlStr.Append(item.Value);
        SqlStr.Append("','");
  
      }
      SqlStr.Remove(SqlStr.Length - 2, 2);
      SqlStr.Append(")");
      Console.WriteLine(SqlStr.ToString());
  
    }
  }
SqlStr中的内容为insert into User(userID,UserName) values('1','lfm')
  前端使用代码:
static void Main(string[] args)
    {
      ORMHelp o = new ORMHelp();
      User u = new User() { UserID=1,UserName="lfm"};
      o.Insert(u);
    }
  特性也是一个Class类型,可以有多个构造函数,就像C#的new语句一样,我们向类型附加特性时可以使用不同的初始化参数来指明使用特性的那个构造函数。我们附加特性时还可以使用“属性名=属性值”的方法来直接指明特性的属性值。该特性中定义了一个TableName属性,该属性就是被修饰的对象所映射的数据库表的名称。
  下面我们举一个使用特性来进行O/RMapping的例子,也就是将对象转化成Sql语句
  用户类:
  User类
  [Table("User")]
  public class User
  {
    [Colum("userID", DbType = DbType.Int32)]
    public int UserID { get; set; }
    [Colum("UserName", DbType = DbType.String)]
    public string UserName { get; set; }
  }
  表特性
[AttributeUsageAttribute(AttributeTargets.Class, Inherited = false, AllowMultiple = false)]
  public class TableAttribute : Attribute
  {
    //保存表名的字段
    private string _tableName;
  
    public TableAttribute()
    {
    }
  
    public TableAttribute(string tableName)
    {
      this._tableName = tableName;
    }
  
    /// <summary>
    /// 映射的表名(表的全名:模式名.表名)
    /// </summary>
    public string TableName
    {
      set
      {
        this._tableName = value;
      }
      get
      {
        return this._tableName;
      }
    }
  }
 


相关教程