对象关系映射,靠纯手打,是个超级繁琐又类的苦力活,即便它能给你再高的运行效率,但是也会损失开发效率。
c#在netframework中其实已经提供了ORM框架了,叫做entity framework,这个框架其实已经做的蛮好的了,但是框架实在是太重,重到写出来的代码在配置不那么好的电脑上跑起来都卡顿。
因此我们决定自己写这么一个框架,一来重在轻量;二来,就是想探探路,看看ORM框架到底是怎么做出来的。
当然,让我自己凭空造楼是做不到的,但是我们可以借鉴,尤其是在互联网这么发达的时代,去github看看别的的开源代码就OK了。
一、反射。
首先我们要解决的就是当从数据库中取出值来了之后,怎么直接赋值给相应的对象的属性的问题,我们记得,传统的做法就是
dt.Rows[i][“ID”]
这么一个一个字段去写,碰到字段比较多的表,那就会打半天了。
反射,就是要获得该类的变量的名称,然后赋值给该变量:
代码如下 | 复制代码 |
public List<T> ExecSelect<T>(string sqlCmd) where T : new() { List<T> list = new List<T>(); DataTable dt = Select(sqlCmd); if (dt.Rows.Count == 0) PropertyInfo[] properties = ReflectionHelper.GetProperties(new T().GetType()); for (int i=0;i<dt.Rows.Count;i++) return list; } |
以上的T就是一种泛型,至于泛型是什么,自行百度。
GetProperties函数即是泛型用于获取类的变量的方法,它有一些参数,包括获取变量为public修饰等等参数:
代码如下 | 复制代码 |
public static PropertyInfo[] GetProperties(Type type) { return type.GetProperties(BindingFlags.Public | BindingFlags.Instance); } |
二、Value.
既然我们已经通过GetProperties获取了该类的属性,那么通过SetValue直接给其赋值就好了,问题是,如果我们从数据库中取出来的值和它不匹配呢,因此我们需要转化Value类型。
代码如下 | 复制代码 |
if (Convert.IsDBNull(value) || (value == null)) { return null; } string typeName = type.FullName.ToString(); if (type == typeof(System.Nullable<UInt16>)) switch (typeName) return value; |
三、反射与动态编译。
Reflection真的是个好东西,但是net4.0后会有一个更好的东西:dynamic,要知道反射其实是很费效率的,但是动态编译就会快的多,如果你不理解dynamic,那么以下的例子就会告诉你这两者的区别:
public void test()
{
SomeClass c = new SomeClass();
PropertyInfo property = c.GetType().GetProperties()[0];
StartTest("begin reflection.");
for (int i = 0; i < 1000000; i++)
{
property.SetValue(c, i, null);
}
EndTest("end reflection");
IDynamicPropertyInfo dproperty = new DynamicType(c.GetType()).GetProperties()[0];
StartTest("begin dynamic.");
for (int i = 0; i < 1000000; i++)
{
dproperty.SetValue(c, i, null);
}
EndTest("end dynamic");
}
那么这两者的时间差呢:
—— Test started: Assembly: Pixysoft.Framework.Reflection.dll ——
begin reflection.
end reflection
00:00:09.0625000
begin dynamic.
end dynamic
00:00:00.0468750
差别就太远了,所以如果你觉得因为反射你的程序变慢了,不如试试动态编译。