`
saybody
  • 浏览: 902971 次
  • 性别: Icon_minigender_2
  • 来自: 西安
文章分类
社区版块
存档分类
最新评论

C#基础系列:实现自己的ORM(反射以及Attribute在ORM中的应用)

阅读更多

反射以及AttributeORM中的应用

<?xml:namespace prefix = o ns = "urn:schemas-microsoft-com:office:office" />

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

  1. publicclassPerson
  2. {
  3. privatestring_Name;
  4. privateint_Age;
  5. privatestring_Sex;
  6. publicstringName
  7. {
  8. get{returnthis._Name;}
  9. set{this._Name=value;}
  10. }
  11. publicintAge
  12. {
  13. get{returnthis._Age;}
  14. set{this._Age=value;}
  15. }
  16. publicstringSex
  17. {
  18. get{returnthis._Sex;}
  19. set{this._Sex=value;}
  20. }
  21. }

测试代码如下:

  1. staticclassProgram
  2. {
  3. [STAThread]
  4. staticvoidMain()
  5. {
  6. Personperson=newPerson();
  7. person.Name="snoopy";
  8. person.Age=5;
  9. person.Sex="male";
  10. PropertyInfo[]infos=person.GetType().GetProperties();
  11. Console.WriteLine("打印属性");
  12. foreach(PropertyInfoinfoininfos)
  13. {
  14. //获取属性并打印
  15. Console.WriteLine(info.Name+":"+info.GetValue(person,null));
  16. }
  17. Console.WriteLine("设置Person.Name=Hellokitty");
  18. //设置属性,设置Name属性
  19. foreach(PropertyInfoinfoininfos)
  20. {
  21. if(info.Name=="Name")
  22. {
  23. info.SetValue(person,"Hellokitty",null);
  24. }
  25. }
  26. Console.WriteLine("打印属性");
  27. foreach(PropertyInfoinfoininfos)
  28. {
  29. //获取属性并打印
  30. Console.WriteLine(info.Name+":"+info.GetValue(person,null));
  31. }
  32. Console.Read();
  33. }
  34. }

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


二、Attribute的使用:
Attribute中文翻译虽然也号称“属性”,但是她和对象的属性(Property)其实是完全不同的两概念。她是在运行时对对象或者对象属性、方法、委托等等进行描述的类,用于在运行时描述你的代码或者在运行时影响你的程序的行为。
其实我们在c#的编程中经常看到Attribute,只不过我们没有注意罢了。比如Main函数前的“[STAThread]”这个其实就是一个Attribute。全程为[STAThreadAttribute]。另外指定类可序列化的[Serializable]等等。是不是都很熟悉啊?只不过平时估计没有用到,所以没有注意罢了。

既然Attribute是类,那么她的定义方法和类就没有两样了,唯一的不同就是自定义Attribute类必须继承于System.Attribute。
下面我们来简单定义一个描述数据库字段信息的Attribute,在此类中我们采用更省略的方式,仅仅提供“字段名”,“字段类型”:

  1. publicclassDataFieldAttribute:Attribute
  2. {
  3. privatestring_FieldName;
  4. privatestring_FieldType;
  5. publicDataFieldAttribute(stringfieldname,stringfieldtype)
  6. {
  7. this._FieldName=fieldname;
  8. this._FieldType=fieldtype;
  9. }
  10. publicstringFieldName
  11. {
  12. get{returnthis._FieldName;}
  13. set{this._FieldName=value;}
  14. }
  15. publicstringFieldType
  16. {
  17. get{returnthis._FieldType;}
  18. set{this._FieldType=value;}
  19. }
  20. }

好,我们有了自己的描述数据库字段的Attribute,那么我们现在将其应用到实际的类中。我们还是继续上面的Person类,使用方法如下:


  1. publicclassPerson
  2. {
  3. privatestring_Name;
  4. privateint_Age;
  5. privatestring_Sex;
  6. [DataFieldAttribute("name","nvarchar")]
  7. publicstringName
  8. {
  9. get{returnthis._Name;}
  10. set{this._Name=value;}
  11. }
  12. [DataFieldAttribute("age","int")]
  13. publicintAge
  14. {
  15. get{returnthis._Age;}
  16. set{this._Age=value;}
  17. }
  18. [DataFieldAttribute("sex","nvarchar")]
  19. publicstringSex
  20. {
  21. get{returnthis._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(关系数据库)的映射规则,下面我们就通过反射的方法来动态获取此映射规则:

  1. staticclassProgram
  2. {
  3. [STAThread]
  4. staticvoidMain()
  5. {
  6. Personperson=newPerson();
  7. person.Name="snoopy";
  8. person.Age=5;
  9. person.Sex="male";
  10. PropertyInfo[]infos=person.GetType().GetProperties();
  11. object[]objDataFieldAttribute=null;
  12. foreach(PropertyInfoinfoininfos)
  13. {
  14. objDataFieldAttribute=info.GetCustomAttributes(typeof(DataFieldAttribute),false);
  15. if(objDataFieldAttribute!=null)
  16. {
  17. Console.WriteLine(info.Name+"->数据库字段:"+((DataFieldAttribute)objDataFieldAttribute[0]).FieldName);
  18. }
  19. }
  20. }
  21. }

哈哈,你是不是很想动手了啊?当然了如果你到了这一步就开始动手的话,那我就很高兴了,说明我的描述还算清楚(注:对于已经知道的大牛们此话无效)。也说明你很有动手的能力。因为接下来的工作就是怎样根据这种方法动态地从对象中获取映射规则,动态构造Insert,Update,Delete等语句。

四、本章总结
本章中我比较详细地介绍了反射,自定义Attribute的概念和应用,并且介绍了怎样在运行时动态获取O/R Mapping的映射规则等。当然我这里的代码仅仅是举例,而要真正实现一个ORM,我们还需要考虑的很多,比如:
1、Person对应于哪张数据库表?
2、Person中的PK和FK(如果有的话)怎么表示?
......
这些问题将在我的下一篇中进行讲解。

相关连接:

C#基础系列:实现自己的ORM(ORM的基础概念)

C#基础系列:实现自己的ORM(构造我自己的ORM)

C#基础系列:实现自己的ORM(MiniORM的测试代码)

源代码下载

分享到:
评论

相关推荐

    使用C#的Attribute(特性)实现一个简单的ORM

    【内容概要】:在C#中通过学习使用Attribute,实现一个简单的ORM框架。里面主要有两部分的内容,学习使用Attribute获得设定值;学习通过反射获取属性的值 【适应人群】:初级工程师。但需要对反射、Attribute有一定...

    自己写的ORM

    这个过程可能涉及到大量代码编写,但能够帮助你更深入地理解数据访问层的内部工作,从而在实际项目中更好地应用和优化ORM技术。同时,通过分享和评估自定义ORM,可以从社区获取反馈,进一步提升自己的编程能力。

    C#实现反射实例和软件

    在编程领域,C#是一种广泛使用的面向对象的编程语言,尤其在开发Windows应用程序、Web服务以及游戏等领域。本文将深入探讨C#中的反射机制及其在实际软件开发中的应用。 反射是.NET Framework提供的一种强大功能,它...

    C#根据反射和特性实现ORM映射实例分析

    ## C#中的反射和特性实现ORM映射详解 ### (一)反射 反射是.NET框架提供的一种强大的机制,它允许程序在运行时动态地获取类型信息并操作类型。简单来说,反射就是程序在运行时检查自身的能力,能够获取类型的信息...

    .net ORM实现代码

    .NET ORM实现代码主要涉及到的对象关系映射(Object-Relational Mapping,简称ORM)技术,这是一种在软件开发中用于简化数据库操作的技术。ORM框架允许开发者使用面向对象的方式与数据库进行交互,而无需直接编写SQL...

    简单的ORM类库,还算好用

    通过学习和使用这个库,开发者可以更好地理解ORM的工作原理,并将其应用到自己的.NET项目中。由于它是一个自实现的小型库,所以可能更适合小型项目或学习目的,对于大型复杂的项目,可能需要更成熟的ORM解决方案,如...

    C#特性标签实现通用Dao层

    这种方法的关键在于利用元数据(特性)来描述实体类和数据库之间的关系,以及利用反射在运行时动态地获取和操作这些信息。在实际项目中,还需要考虑事务管理、错误处理、性能优化等因素,以确保Dao层的稳定性和高效...

    C#从入门到精通、c#高级编程

    在IT领域,C#是一种广泛使用的面向对象的编程语言,由微软公司开发并应用于Windows操作系统、Web应用以及游戏开发等多个场景。"C#从入门到精通"和"C#高级编程"这两本书是学习C#语言的重要资源,涵盖了从基础知识到...

    C#通用权限

    在IT行业中,尤其是在软件开发领域,权限管理是一个至关重要的部分,尤其对于企业级应用来说更是如此。C#作为.NET框架的主要编程语言,提供了强大的工具和技术来实现通用权限系统。本篇将详细介绍“C#通用权限”这一...

    C#反射机制详细概括

    本文将详细介绍C#反射机制的工作原理及其在实际开发中的重要应用。 #### 二、C#反射的基本概念 反射(Reflection)是指在运行时检查和修改程序结构和行为的能力。在.NET Framework中,反射主要由三个核心类提供...

    c#类库(很多种总有你要用的)

    5. **AOP(面向切面编程)**:C# 中可以通过 `Attribute` 实现轻量级的 AOP,比如 `DebuggerStepThrough` 属性可以控制调试器的行为,或者 `CLSCompliant` 检查代码是否符合 CLS(公共语言规范)。 6. **反射**:C#...

    Visual C# .NET程序设计经典 配套资源

    8. **AOP(Aspect-Oriented Programming)**:C#中的特性(Attribute)可以实现面向切面编程,允许将关注点如日志、事务管理等分离出来,提高代码的可维护性。 9. **Entity Framework**:这是一款ORM(Object-...

    c#实战100例

    15. **反射与元数据**:通过反射技术动态地获取和操作类型信息,以及使用Attribute实现元数据注解。 这些实例覆盖了C#编程的广泛领域,无论是初学者还是有经验的开发者,都能从中受益。通过实际动手操作,将理论...

    scau 华农 C#期末考复习资料

    8. **特性(Attribute)**:了解特性在代码中的应用,知道如何自定义和使用特性。 【C#与.NET框架】 了解.NET Framework提供的各种服务,如Windows Forms和WPF用于桌面应用开发,ASP.NET用于Web应用开发,以及...

    c#权限管理系统.zip

    在IT行业中,权限管理系统是构建安全、高效应用的关键组成部分,特别是在多用户环境中。本文将深入探讨基于C#的权限管理系统的实现与设计,以及相关的技术要点。 标题“c#权限管理系统.zip”暗示了这是一个使用C#...

    特性与反射得出sql语句

    在.NET编程环境中,C#语言提供了强大的特性(Attribute)和反射(Reflection)功能,这两个概念在软件开发中扮演着至关重要的角色,特别是在元数据管理和动态代码执行方面。本篇文章将详细探讨“特性与反射得出SQL...

    CSharp Rod ORM 持久化框架

    本人开发基于C# Attribute 声明式的ORM 框架,自带Sqlite数据库的一个测试例子。 本框架的特点: 1. 无XML配置,基于Attribute的配置方式 2. 可自定义mapping的约定,只需在Model类定义Entity,按约定映射对应的表及...

    Sqlserver转C#代码生成

    在IT行业中,代码生成是一种常见的开发工具和技术,用于自动化编程过程中的重复性任务,从而提高效率和准确性。针对“Sqlserver转C#代码生成”的主题,我们主要关注如何从SQL Server数据库中获取表结构信息,并自动...

    C#与.NET3.5高级程序设计(16-17章)中文pdf

    《C#与.NET3.5高级程序设计》的16-17章涵盖了两个关键的高级主题:类型反射、晚期绑定和基于特性的编程,以及进程、应用程序域和对象上下文。这两个章节深入探讨了.NET Framework的核心机制,帮助开发者更好地理解和...

Global site tag (gtag.js) - Google Analytics