本文实例讲述了C#根据反射和特性实现ORM 映射的方法。分享给大家供大家参考。具体如下:

(一)关于反射

什么是反射?

反射就是在运行时,动态获取对象信息的方法。比如:运行时获得对象有哪些属性,方法,委托等。

反射的作用?

能够实现运行时,动态调用对象的方法,以及动态设置、获取属性值等。

反射的示例:

using System;
using System.Reflection;
namespace CS_Test
{
public class MyStudent
{
private string sName;
public string SName
{
get { return sName; }
set { sName = value; }
}
private int sAge;
public int SAge
{
get { return sAge; }
set { sAge = value; }
}
}
class Test_Attribute
{
[STAThread]
static void Main(string[] args)
{
MyStudent stu1 = new MyStudent();
stu1.SName = "刘德华";
stu1.SAge = ;
// 获得所有属性
PropertyInfo[] pros = stu1.GetType().GetProperties();
// 显示所有属性值
foreach (PropertyInfo pro in pros)
Console.WriteLine(pro.Name+":"+pro.GetValue(stu1,null));
//更改stu1对象的SAge值
stu1.GetType().GetProperty("SAge").SetValue(stu1, , null);
// 显示所有属性值
foreach (PropertyInfo pro in pros)
Console.WriteLine(pro.Name+":"+pro.GetValue(stu1, null));
}
}
}

(二)关于特性

什么是 Attribute?

它是对运行时的对象或对象的属性、方法、委托等进行描述的类。
Attribute 的作用?
用于在运行时,描述你的代码或者影响你的程序的行为。

注意:

既然Attribute 是类,那么它的定义与定义类一样。
唯一不同的就是,自定义Attribute 类必须继承于System.Attribute 空间。
特性的示例:

//描述数据库字段的 Attribute
public class DataFieldAttribute : Attribute
{
public DataFieldAttribute(string fieldName,string fieldType)
{
this._fieldName = fieldName;
this._fieldType = fieldType;
}
// 数据库字段名
private string _fieldName;
public string FieldName
{
get { return _fieldName; }
set { _fieldName = value; }
}
// 数据库字段类型
private string _fieldType;
public string FieldType
{
get { return _fieldType; }
set { _fieldType = value; }
}
}

通过自定义Attribute,我们定义了类属性和数据库字段的一一对应关系,于是对MyStudent 类的Name、Age 属性都加上Attribute 的描述,指定他们对应的数据库字段名以及类型。
代码更改如下:

public class MyStudent
{
private string _name;
//使用“特性”描述对应的数据库字段名、类型
[DataFieldAttribute("SName", "varchar")]
public string Name
{
get { return _name; }
set { _name = value; }
}
private int _age;
[DataFieldAttribute("SAge", "int")]
public int Age
{
get { return _age; }
set { _age = value; }
}
}

(三)ORM 映射规则的定义

给实体类增加DataFieldAttribute 的描述,其实就是增加了O(对象)/ R(关系数据库)的映射规则。
下面我们就通过反射的方法实现:在运行时动态获取O/R  Mapping 的映射规则:

static void Main(string[] args)
{
MyStudent stu1 = new MyStudent();
stu1.Name = "刘德华";
stu1.Age = ;
//通过反射的方法来动态获取此映射规则
PropertyInfo[] infos = stu1.GetType().GetProperties();
object[] objs_fieldAttr = null;
foreach (PropertyInfo info in infos)
{
// GetCustomAttributes:
// 返回实体对象中每个属性对应的“特性”信息(数据库字段名、类型)
objs_fieldAttr = info.GetCustomAttributes(
typeof(DataFieldAttribute), false);
if (objs_fieldAttr != null)
{
Console.Write("实体类的属性名:" + info.Name);
Console.Write(" -> 数据库字段名:");
Console.WriteLine(((DataFieldAttribute)objs_fieldAttr[]).FieldName);
}
}
}

显示结果:

实体类的属性名:Name -> 数据库字段名:SName
实体类的属性名:Age -> 数据库字段名:SAge
 
接下来的工作就是:怎样根据这种方法动态地从对象中获取映射规则,然后动态构造Insert、Update、Delete 等 SQL 语句。这就是实现自己的ORM 的原理。
 
这里的代码仅仅是举例,而要真正实现一个ORM,我们还需要考虑的很多,比如:

1、实体类对应于哪张数据库表?
2、数据库表中的 PK  和 FK(如果有的话)怎么表示?

完整代码如下:

using System;
using System.Reflection;
namespace CS_Test
{
public class MyStudent
{
private string _name;
//使用“特性”描述对应的数据库字段名、类型
[DataFieldAttribute("SName", "varchar")]
public string Name
{
get { return _name; }
set { _name = value; }
}
private int _age;
[DataFieldAttribute("SAge", "int")]
public int Age
{
get { return _age; }
set { _age = value; }
}
}
//描述数据库字段的 Attribute
public class DataFieldAttribute : Attribute
{
public DataFieldAttribute(string fieldName,string fieldType)
{
this._fieldName = fieldName;
this._fieldType = fieldType;
}
// 数据库字段名
private string _fieldName;
public string FieldName
{
get { return _fieldName; }
set { _fieldName = value; }
}
// 数据库字段类型
private string _fieldType;
public string FieldType
{
get { return _fieldType; }
set { _fieldType = value; }
}
}
class Test_Attribute
{
[STAThread]
static void Main(string[] args)
{
MyStudent stu1 = new MyStudent();
stu1.Name = "刘德华";
stu1.Age = ;
// 获得所有属性
PropertyInfo[] pros = stu1.GetType().GetProperties();
// 显示所有属性值
foreach (PropertyInfo pro in pros)
Console.WriteLine(pro.Name+":"+pro.GetValue(stu1,null));
//更改stu1对象的SAge值
stu1.GetType().GetProperty("Age").SetValue(stu1, , null);
// 显示所有属性值
foreach (PropertyInfo pro in pros)
Console.WriteLine(pro.Name+":"+pro.GetValue(stu1, null)); //通过反射的方法来动态获取此映射规则
PropertyInfo[] infos = stu1.GetType().GetProperties();
object[] objs_fieldAttr = null;
foreach (PropertyInfo info in infos)
{
// GetCustomAttributes:
// 返回实体中每个属性对应的“特性”信息(数据库字段名、类型)
objs_fieldAttr = info.GetCustomAttributes(
typeof(DataFieldAttribute), false);
if (objs_fieldAttr != null)
{
Console.Write("实体类的属性名:" + info.Name);
Console.Write(" -> 数据库字段名:");
Console.WriteLine(((DataFieldAttribute)objs_fieldAttr[]).FieldName);
}
}
}
}
}

最新文章

  1. AgileEAS.NET SOA中间件平台更新日志 2015-04-28
  2. python简单文件操作
  3. Twitter API 申请key
  4. paip.一千 常用汉字 高频汉字 覆盖率90%
  5. php 方便快捷导出excel
  6. centos 6.4下的postgresql 9.2使用
  7. 【转】基本数据持久性(一) 使用plist保存和读取数据
  8. CentOS修改主机名hostname
  9. 【扩展欧几里德】Vijos P1009 清帝之惑之康熙
  10. Ring3下干净的强行删除文件
  11. Linux文件系统概述
  12. Python数据挖掘和机器学习
  13. Java 之 OOAD
  14. linux下设置计划任务执行python脚本
  15. "java.lang.IllegalStateException: No instrumentation registered! Must run under a registering instrumentation."问题解决
  16. An error occurred (500 Error)
  17. jQuery操作DOM节点的方法总结
  18. verilog中defparam的用法 (verilog调用底层模块(只改变)参数的传递)
  19. .NET实现自动编译
  20. 浅谈Spring中的事务回滚

热门文章

  1. HDU 5971 二分图判定
  2. A1042 Shuffling Machine (20)
  3. 关于欧几里德算法(gcd)的证明
  4. 快速排序,对于相同元素的优化,c++
  5. 最近使用Nginx的一点新得
  6. sql中保留一位小数的百分比字符串拼接,替换函数,换行符使用
  7. F#周报2019年第25期
  8. BZOJ 4247: 挂饰
  9. Beamer模板
  10. 虚拟机安装教程(linux、centOS)