• 设为首页
  • 点击收藏
  • 手机版
    手机扫一扫访问
    迪恩网络手机版
  • 关注官方公众号
    微信扫一扫关注
    公众号

C#:反射以及Attribute在ORM中的应用

原作者: [db:作者] 来自: [db:来源] 收藏 邀请

一、 反射

  什么是反射?

  简单点吧,反射就是在运行时动态获取对象信息的方法,比如运行时知道对象有哪些属性,方法,委托等等等等。

  反射有什么用呢?

  反射不但让你在运行是获取对象的信息,还提供运行时动态调用对象方法以及动态设置、获取属性等的能力。

  反射在ORM中有什么用呢?

  我这里所讨论的ORM实现是通过自定义Attribute的方式进行映射规则的描述的。但是我们并不知道具体哪个对象需要对应哪个表,并且这些对象是独立于我们的ORM框架的,所以我们只能通过自定义Attribute来定义映射规则,然后通过反射来动态获取这些映射规则。

  反射的实现:

  下面我们就以简单的获取对象的属性值的方式来做讨论,假设我们有类Person,其中有3个属性Name、Age,Sex。我们通过反射的方法来动态获取Person的对象的这三个属性的值。

public class Person
{
  private string _Name;
  private int _Age;
  private string _Sex;
  public string Name
  {
    get { return this._Name; }
    set { this._Name = value; }
  }
  public int Age
  {
    get { return this._Age; }
    set { this._Age = value; }
  }
  public string Sex
  {
    get { return this._Sex; }
    set { this._Sex = value; }
  }
}
        测试代码如下:

static class Program
{
  [STAThread]
  static void Main()
  {
    Person person = new Person();
    person.Name = "snoopy";
    person.Age = 5;
    person.Sex = "male";
    PropertyInfo[] infos = person.GetType().GetProperties();
    Console.WriteLine("打印属性");
    foreach (PropertyInfo info in infos)
    {
      //获取属性并打印
      Console.WriteLine(info.Name + ":" + info.GetValue(person, null));
    }
    Console.WriteLine("设置Person.Name = Hellokitty");
    //设置属性,设置Name属性
    foreach (PropertyInfo info in infos)
    {
      if (info.Name == "Name")
      {
        info.SetValue(person, "Hellokitty", null);
      }
    }
    Console.WriteLine("打印属性");
    foreach (PropertyInfo info in infos)
    {
      //获取属性并打印
      Console.WriteLine(info.Name + ":" + info.GetValue(person, null));
    }
    Console.Read();
  }
}
        执行结果:

       

         上面演示了通过反射的方法来动态获取和设置对象属性的方法。但是这和ORM以及Attribute有什么关系呢?这个是我们接下来的这个部分的内容。

  上面演示了通过反射的方法来动态获取和设置对象属性的方法。但是这和ORM以及Attribute有什么关系呢?这个是我们接下来的这个部分的内容。

  二、Attribute的使用:

  Attribute中文翻译虽然也号称“属性”,但是她和对象的属性(Property)其实是完全不同的两概念。她是在运行时对对象或者对象属性、方法、委托等等进行描述的类,用于在运行时描述你的代码或者在运行时影响你的程序的行为。

  其实我们在c#的编程中经常看到Attribute,只不过我们没有注意罢了。比如Main函数前的“[STAThread]”这个其实就是一个Attribute。全程为[STAThreadAttribute]。另外指定类可序列化的[Serializable]等等。是不是都很熟悉啊?只不过平时估计没有用到,所以没有注意罢了。

  既然Attribute是类,那么她的定义方法和类就没有两样了,唯一的不同就是自定义Attribute类必须继承于System.Attribute。

  下面我们来简单定义一个描述数据库字段信息的Attribute,在此类中我们采用更省略的方式,仅仅提供“字段名”,“字段类型”:

public class DataFieldAttribute : Attribute
{
  private string _FieldName;
  private string _FieldType;
  public DataFieldAttribute(string fieldname, string fieldtype)
  {
    this._FieldName = fieldname;
    this._FieldType = fieldtype;
  }
  public string FieldName
  {
    get { return this._FieldName; }
    set { this._FieldName = value; }
  }
  public string FieldType
  {
    get { return this._FieldType; }
    set { this._FieldType = value; }
  }
}
        好,我们有了自己的描述数据库字段的Attribute,那么我们现在将其应用到实际的类中。我们还是继续上面的Person类,使用方法如下:

public class Person
{
  private string _Name;
  private int _Age;
  private string _Sex;
  [DataFieldAttribute("name", "nvarchar")]
  public string Name
  {
    get { return this._Name; }
    set { this._Name = value; }
  }
  [DataFieldAttribute("age", "int")]
  public int Age
  {
    get { return this._Age; }
    set { this._Age = value; }
  }
  [DataFieldAttribute("sex", "nvarchar")]
  public string Sex
  {
    get { return this._Sex; }
    set { this._Sex = value; }
  }
}
        通过自定义Attribute,我们定义了类属性和数据库字段的一一对应关系,我们对Person类的Name、Age、Sex属性都加上了Attribute的描述,指定了他们对应的字段名以及类型,其中Person.Name对应于字段name,字段类型Nvarchar...。

  三、反射和Attribute的联合使用。

  从上面的描述中,我们了解了反射,了解了Attribute,了解了ORM映射规则的定义。但是刚接触的朋友估计还是迷惑,我们怎么动态获取这些映射规则呢?

  这就需要使用反射了:

  下面的例子,我们由于对Person中的Name,Age以及SEX都增加了DataFieldAttribute的描述,这其实就是增加了O(对象)/R(关系数据库)的映射规则,下面我们就通过反射的方法来动态获取此映射规则:

static class Program
{
  [STAThread]
  static void Main()
  {
    Person person = new Person();
    person.Name = "snoopy";
    person.Age = 5;
    person.Sex = "male";
    PropertyInfo[] infos = person.GetType().GetProperties();
    object[] objDataFieldAttribute = null;
    foreach (PropertyInfo info in infos)
    {
      objDataFieldAttribute = info.GetCustomAttributes(typeof(DataFieldAttribute), false);
      if (objDataFieldAttribute != null)
      {
        Console.WriteLine(info.Name + "->数据库字段:" + ((DataFieldAttribute)objDataFieldAttribute[0]).FieldName);
      }
    }
  }
}
        测试结果:

 

  接下来的工作就是怎样根据这种方法动态地从对象中获取映射规则,动态构造Insert,Update,Delete等语句。

  四、本章总结

  本章中比较详细地介绍了反射,自定义Attribute的概念和应用,并且介绍了怎样在运行时动态获取O/R Mapping的映射规则等。当然我这里的代码仅仅是举例,而要真正实现一个ORM,我们还需要考虑的很多,比如:

  1、Person对应于哪张数据库表?

  2、Person中的PK和FK(如果有的话)怎么表示?

  ......
 

本篇文章来源于:开发学院 http://edu.codepub.com   原文链接:http://edu.codepub.com/2010/0212/20428.php


鲜花

握手

雷人

路过

鸡蛋
该文章已有0人参与评论

请发表评论

全部评论

专题导读
上一篇:
总结:C#变量,占位符等相关知识发布时间:2022-07-13
下一篇:
C#使用ListView更新数据出现闪烁解决办法发布时间:2022-07-13
热门推荐
热门话题
阅读排行榜

扫描微信二维码

查看手机版网站

随时了解更新最新资讯

139-2527-9053

在线客服(服务时间 9:00~18:00)

在线QQ客服
地址:深圳市南山区西丽大学城创智工业园
电邮:jeky_zhao#qq.com
移动电话:139-2527-9053

Powered by 互联科技 X3.4© 2001-2213 极客世界.|Sitemap