反射以及Attribute在ORM中的应用

本文深入探讨了在对象关系映射(ORM)中如何利用反射和自定义Attribute实现动态获取对象属性与数据库字段的映射规则。通过具体示例,展示了如何定义描述数据库字段信息的Attribute,并使用反射在运行时获取这些映射规则。

GPS平台、网站建设、软件开发、系统运维,找森大网络科技!
http://cnsendnet.taobao.com
来自森大科技官方博客
http://www.cnsendblog.com/index.php/?p=488

反射以及Attribute在ORM中的应用
一、 反射
什么是反射?
简单点吧,反射就是在运行时动态获取对象信息的方法,比如运行时知道对象有哪些属性,方法,委托等等等等。
反射有什么用呢?
反射不但让你在运行是获取对象的信息,还提供运行时动态调用对象方法以及动态设置、获取属性等的能力。
反射在ORM中有什么用呢?
我这里所讨论的ORM实现是通过自定义Attribute的方式进行映射规则的描述的。但是我们并不知道具体哪个对象需要对应哪个表,并且这些对象是独立于我们的ORM框架的,所以我们只能通过自定义Attribute来定义映射规则,然后通过反射来动态获取这些映射规则。
反射的实现:
下面我们就以简单的获取对象的属性值的方式来做讨论,假设我们有类Person,其中有3个属性Name、Age,Sex。我们通过反射的方法来动态获取Person的对象的这三个属性的值。

  1. public class Person

  2. {

  3. private string _Name;

  4. private int _Age;

  5. private string _Sex;

  6. public string Name

  7. {

  8. get { return this._Name; }

  9. set { this._Name = value; }

  10. }

  11. public int Age

  12. {

  13. get { return this._Age; }

  14. set { this._Age = value; }

  15. }

  16. public string Sex

  17. {

  18. get { return this._Sex; }

  19. set { this._Sex = value; }

  20. }

  21. }
    测试代码如下:

  22. static class Program

  23. {

  24. [STAThread]

  25. static void Main()

  26. {

  27. Person person = new Person();

  28. person.Name = “snoopy”;

  29. person.Age = 5;

  30. person.Sex = “male”;

  31. PropertyInfo[] infos = person.GetType().GetProperties();

  32. Console.WriteLine(“打印属性”);

  33. foreach (PropertyInfo info in infos)

  34. {

  35. //获取属性并打印

  36. Console.WriteLine(info.Name + “:” + info.GetValue(person, null));

  37. }

  38. Console.WriteLine(“设置Person.Name = Hellokitty”);

  39. //设置属性,设置Name属性

  40. foreach (PropertyInfo info in infos)

  41. {

  42. if (info.Name == “Name”)

  43. {

  44. info.SetValue(person, “Hellokitty”, null);

  45. }

  46. }

  47. Console.WriteLine(“打印属性”);

  48. foreach (PropertyInfo info in infos)

  49. {

  50. //获取属性并打印

  51. Console.WriteLine(info.Name + “:” + info.GetValue(person, null));

  52. }

  53. Console.Read();

  54. }

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

二、Attribute的使用:
Attribute中文翻译虽然也号称“属性”,但是她和对象的属性(Property)其实是完全不同的两概念。她是在运行时对对象或者对象属性、方法、委托等等进行描述的类,用于在运行时描述你的代码或者在运行时影响你的程序的行为。
其实我们在c#的编程中经常看到Attribute,只不过我们没有注意罢了。比如Main函数前的“[STAThread]”这个其实就是一个Attribute。全程为[STAThreadAttribute]。另外指定类可序列化的[Serializable]等等。是不是都很熟悉啊?只不过平时估计没有用到,所以没有注意罢了。
既然Attribute是类,那么她的定义方法和类就没有两样了,唯一的不同就是自定义Attribute类必须继承于System.Attribute。
下面我们来简单定义一个描述数据库字段信息的Attribute,在此类中我们采用更省略的方式,仅仅提供“字段名”,“字段类型”:
62. public class DataFieldAttribute : Attribute
63. {
64. private string _FieldName;
65. private string _FieldType;
66.
67. public DataFieldAttribute(string fieldname, string fieldtype)
68. {
69. this._FieldName = fieldname;
70. this._FieldType = fieldtype;
71. }
72.
73. public string FieldName
74. {
75. get { return this._FieldName; }
76. set { this._FieldName = value; }
77. }
78.
79. public string FieldType
80. {
81. get { return this._FieldType; }
82. set { this._FieldType = value; }
83. }
84. }
好,我们有了自己的描述数据库字段的Attribute,那么我们现在将其应用到实际的类中。我们还是继续上面的Person类,使用方法如下:

  1. public class Person
  2. {
  3. private string _Name;
  4. private int _Age;
  5. private string _Sex;
  6. [DataFieldAttribute(“name”, “nvarchar”)]
  7. public string Name
  8. {
  9. get { return this._Name; }
  10. set { this._Name = value; }
  11. }
  12. [DataFieldAttribute(“age”, “int”)]
  13. public int Age
  14. {
  15. get { return this._Age; }
  16. set { this._Age = value; }
  17. }
  18. [DataFieldAttribute(“sex”, “nvarchar”)]
  19. public string Sex
  20. {
  21. get { return this._Sex; }
  22. set { this._Sex = value; }
  23. }
  24. }
    通过自定义Attribute,我们定义了类属性和数据库字段的一一对应关系,我们对Person类的Name、Age、Sex属性都加上了Attribute的描述,指定了他们对应的字段名以及类型,其中Person.Name对应于字段name,字段类型Nvarchar…。
    三、反射和Attribute的联合使用。
    从上面的描述中,我们了解了反射,了解了Attribute,了解了ORM映射规则的定义。但是刚接触的朋友估计还是迷惑,我们怎么动态获取这些映射规则呢?听洒家慢慢道来。
    这就需要使用反射了:
    下面的例子,我们由于对Person中的Name,Age以及SEX都增加了DataFieldAttribute的描述,这其实就是增加了O(对象)/R(关系数据库)的映射规则,下面我们就通过反射的方法来动态获取此映射规则:
  25. static class Program
  26. {
  27. [STAThread]
  28. static void Main()
  29. {
  30. Person person = new Person();
  31. person.Name = “snoopy”;
  32. person.Age = 5;
  33. person.Sex = “male”;
  34. PropertyInfo[] infos = person.GetType().GetProperties();
  35. object[] objDataFieldAttribute = null;
  36. foreach (PropertyInfo info in infos)
  37. {
  38. objDataFieldAttribute = info.GetCustomAttributes(typeof(DataFieldAttribute), false);
  39. if (objDataFieldAttribute != null)
  40. {
  41. Console.WriteLine(info.Name + “->数据库字段:” + ((DataFieldAttribute)objDataFieldAttribute[0]).FieldName);
  42. }
  43. }
  44. }
  45. }

在这里插入图片描述
哈哈,你是不是很想动手了啊?当然了如果你到了这一步就开始动手的话,那我就很高兴了,说明我的描述还算清楚(注:对于已经知道的大牛们此话无效)。也说明你很有动手的能力。因为接下来的工作就是怎样根据这种方法动态地从对象中获取映射规则,动态构造Insert,Update,Delete等语句。
四、本章总结
本章中我比较详细地介绍了反射,自定义Attribute的概念和应用,并且介绍了怎样在运行时动态获取O/R Mapping的映射规则等。当然我这里的代码仅仅是举例,而要真正实现一个ORM,我们还需要考虑的很多,比如:
1、Person对应于哪张数据库表?
2、Person中的PK和FK(如果有的话)怎么表示?

这些问题将在我的下一篇中进行讲解。

GPS平台、网站建设、软件开发、系统运维,找森大网络科技!
http://cnsendnet.taobao.com
来自森大科技官方博客
http://www.cnsendblog.com/index.php/?p=488

MATLAB主动噪声和振动控制算法——对较大的次级路径变化具有鲁棒性内容概要:本文主要介绍了一种在MATLAB环境下实现的主动噪声和振动控制算法,该算法针对较大的次级路径变化具有较强的鲁棒性。文中详细阐述了算法的设计原理与实现方法,重点解决了传统控制系统中因次级路径动态变化导致性能下降的问题。通过引入自适应机制和鲁棒控制策略,提升了系统在复杂环境下的稳定性和控制精度,适用于需要高精度噪声与振动抑制的实际工程场景。此外,文档还列举了多个MATLAB仿真实例及相关科研技术服务内容,涵盖信号处理、智能优化、机器学习等多个交叉领域。; 适合人群:具备一定MATLAB编程基础和控制系统理论知识的科研人员及工程技术人员,尤其适合从事噪声与振动控制、信号处理、自动化等相关领域的研究生和工程师。; 使用场景及目标:①应用于汽车、航空航天、精密仪器等对噪声和振动敏感的工业领域;②用于提升现有主动控制系统对参数变化的适应能力;③为相关科研项目提供算法验证与仿真平台支持; 阅读建议:建议读者结合提供的MATLAB代码进行仿真实验,深入理解算法在不同次级路径条件下的响应特性,并可通过调整控制参数进一步探究其鲁棒性边界。同时可参考文档中列出的相关技术案例拓展应用场景。
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值