今天真好。保持微笑。真好,哈哈。
7月15日 星期三 天气晴
昨天带着遗憾离开了,因为泛型方法的动态调用的问题,还没有得到很好的解决。今天一定要把它干了!
10:18--------终于成功。马上要写一篇日志,记录反射技术的使用心得。
-----------------------------------------------------------------------------------------------------------------------------------------------
关于反射
反射是在运行时获得类、方法等的信息,并加以使用的一种技术。
看看我要做什么吧:
LINQ中每一个数据表对应一个实体类,而表中的每一条记录对应一个实体类对象。
现在我首先要将这些数据表记录从数据库中读出来,变成一个个实体类对象,然后再把他们序列化,写入到二进制文件中。
从数据库读记录出来,用的是这样一条语句: Table<TEntity> table = database.GetTable<TEntity>. database这个变量是一个DataContext,等于是一个数据库的映射,Table<T>类是System.Data.Linq空间下的一个类,是一个实现了IEmurable泛型接口的,可以用GetEmurator,得到一个迭代器,即是TEntity这个实体类的所有类对象的集合。(这些对象的集合其实就是数据记录的集合了)
本来是很简单的,问题是,如果有100个表,那难道我要写100条上面的语句(TEntity换成具体的实体类名)来获得100个table吗?这肯定是不可行的,所以唯一的解决方法就是动态调用泛型方法!
怎么做呢?
利用反射技术就可以达到目的了。利用三点:一:Type类型描述和记录实体类信息 二:反射技术对方法的动态调用 三:泛型方法的调用
首先,使用一个容器类,当然可以是泛型容器了,里面装上所有实体类的类型Type,比如这个容器是List<Type> typelist;
typelist.add(typeof(sys_Control));
typelist.add(typeof(sys_User));
............
将100个实体类型全部装载进去,好的。
第二步,写一个方法,注意必须是公用方法,否则是动态调用不了的。因为找不到。
比如说,我现在要获得每一个实体类的类对象的个数。其实也就是每一个数据表的记录数了。
好的,那这个方法是
public static int getTableCount<T>() where T:class{
Table<T> table = database.GetTable<T> ();
return table.Count<T>();
}
where语句是对泛型的约束,上一篇已经讲过了,这句话是说类型T必须是引用类型的。
好的,现在就来调用这个泛型方法:
Type t = typelist[0];
MethodInfo method = typeof(****Class).GetMethod(“getTableCount”);
MethodInfo gmethod = method.MakeGenericMethod(t);
int result = (int)gmethod.Invoke(null,null);
注意typeof里面的是含有泛型方法的类名。这里应该有一个foreach来迭代这个容器的,就不写了,看得明白就行。GetMethod的参数是方法名,是字符串类型的,用他来查找这个方法,注意方法一定要是公共的才能找到。
还有一点我不是非常确定的是,动态调用的方法不知道是不是一定要是静态方法,应该如果不用静态方法的话,运行中会返回一个TargetException。欢迎大家探讨。
用这样的动态方法调用,感觉挺爽,但是调试起来就比较麻烦,因为动态调用的方法中任何一条语句抛出异常,VS都只会帮你定位到int result = (int)gmethod.Invoke(null,null);这里,所以要F11来找出抛异常那条语句。
PS:今天找BUg的时候还发现一个问题,就是不可以再外部没有订阅事件的情况下来激发一个事件,不然就会抛异常~也就是说如果你激发一个事件,你要保证一定要有一个EventsHandler来处理这个事件。
-----------------------------------------------------------------------------------------------------------------------------------------------------
14:59----------解决了一个小问题。由于项目中有一个需求是设置数据库连接参数。也就是说,程序在运行的过程中可以更改数据库连接,而项目中的数据库连接参数是写死在Settings.setting里面的,因此我要做的只是读写这个类里面的内容就行了。c#做的的确很人性化,可以直接在数据表视图中修改。但是要注意一点:就是作用范围是Application的话,运行时无法改变,要作用范围是User才可以。
参考了这篇日志:
http://www.cnblogs.com/wuming/archive/2008/10/09/1306992.html
16:02---------刚刚有点不知道在做什么。Shit。不要分心。接下来是将数据连接转移到本地数据库上面,然后做数据恢复。做好恢复之后做上传,下载模块,做好后几乎就完工了。本周完成吧。加油。