先看一个简单的例子
[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 = (TalbeAttribute)type.GetCustomAttributes(typeof(TalbeAttribute), 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);
        }

转载于:https://www.cnblogs.com/30ErLi/archive/2010/09/14/1825568.html

反射学习系列2-特性(Attribute)相关推荐

  1. 反射学习系列3-反射实例应用

    反射学习系列目录 反射学习系列1-反射入门 反射学习系列2-特性(Attribute) 反射学习系列3-反射实例应用 作者 例子这个东西其实挺难弄得,弄个简单的,虽然能说明问题但却容易让人觉得没实用价 ...

  2. 反射学习系列1-反射入门

    反射学习系列目录 反射学习系列1-反射入门 反射学习系列2-特性(Attribute) 反射学习系列3-反射实例应用 作者 Reflection,中文翻译为反射.这是.Net中获取运行时类型信息的方式 ...

  3. Java | 学习系列 Java1.8 新特性详解( 包含学习代码 )

    前言: Java 8 已经发布很久了,很多报道表明Java 8 是一次重大的版本升级.在Java Code Geeks上已经有很多介绍Java 8新特性的文章,例如Playing with Java ...

  4. 狂神学习系列11:SpringBoot

    狂神学习系列11:SpringBoot 声明: 本文章是基于狂神的课程所编写,本人才疏学浅,内容仅作参考 项目和markdown文件资料: 07_SpringBoot: 基于狂神说SpringBoot ...

  5. Android学习系列(10)--App列表之拖拽ListView(上)

    研究了很久的拖拽ListView的实现,受益良多,特此与尔共飨.       鉴于这部分内容网上的资料少而简陋,而具体的实现过程或许对大家才有帮助,为了详尽而不失真,我们一步一步分析,分成两篇文章. ...

  6. 数据库MYSQL学习系列三

    数据库MYSQL学习系列三 三.MYSQL事务与存储引擎 3.1-数据库事务 什么是事务 一系列有序的数据库操作: o要么全部成功 o要么全部回退到操作前的状态 o中间状态对其他连接不可见 事务的 ...

  7. ASP.NET MVC 3.0学习系列文章—Model in ASP.NET MVC 3.0

    系列文章 ASP.NET MVC 3.0学习系列文章-序 ASP.NET MVC 3.0学习系列文章--Razor and ASP.NET MVC 3.0 ASP.NET MVC 3.0学习系列文章- ...

  8. 数据库MYSQL学习系列一

    数据库MYSQL学习系列一 一.MYSQL数据库基础 1.1-认识MYSQL 什么是数据库 计算机处理和存储的一切信息都是数据 计算机系统中一种用于存取数据的程序 一种: 计算机系统中有很多种能够存取 ...

  9. iOS学习系列 - 扩展机制category与associative

    iOS学习系列 - 扩展机制category与associative category与associative作为objective-c的扩展机制的两个特性,category即类型,可以通过它来扩展方 ...

最新文章

  1. 来谈下高并发和分布式中的幂等处理
  2. 1.4 Matplotlib:绘图
  3. MySQL中如何创建表与删除表
  4. 奋战杭电ACM(DAY10)1015
  5. 配置V530交换机步骤
  6. 初学者python笔记(面向对象编程、类与对象)
  7. python3入门与进阶 网盘_python3入门与进阶(二)
  8. bzoj2599 [IOI2011]Race
  9. Runtime Message Forwarding
  10. paip.proxool连接池 :Attempt to refer to a unregistered pool by its alias 'xx'
  11. soapui直接下载响应内容为本地的文件
  12. 安装Windows系统时进行磁盘格式化及分区等操作
  13. 信息搜集之CDN知识
  14. ESD5V5U5ULC TVS DIODE SC74-6 TVS - 二极管
  15. python如何计算概率事件_145、Python实现概率分布
  16. 笔记本电脑开机黑屏只能看到鼠标箭头
  17. tomcat7的下载和安装配置
  18. 个人小程序笔记(辅助专用)
  19. codeforces.1253 B
  20. ensp系统服务器是哪个,ensp主机和服务器配置

热门文章

  1. ren命令linux,Linux mren命令
  2. 联想e52进入bios_联想昭阳E52-80笔记本win10怎么改win7
  3. C语言抽象类声明方法,抽象类 – 在C语言中隐藏实现
  4. php加载lrc,javascript - 【求助】php如何获取虾米网的LRC地址?
  5. java gpio_单片机基础——使用GPIO输出点亮一个LED灯
  6. linux指令list by time,tar - Linux 常用命令
  7. php date t_php date 参数
  8. 同频切换的事件_LTE前台路测切换问题处理大礼包
  9. 档案电子封装包Java类,email: Android电子邮件库(基于JavaMail封装)
  10. 乌班图服务器系统怎么配ip,Ubuntu server14-04 服务器双网卡怎么配置静态ip