绕了个大弯子,居然...

    Ensembl上下载的以文本格式保存的数据导入到数据库中。这是生物信息软件开发课程的一次上机任务。事实上老师为了照顾我们这些完全不懂java的家伙,早就把代码写好了,目标数据库是MySQL. 我却打算把数据导入到SQL Server中,java又不懂,只好从头用C#写一遍了,就当是了解ADO.NET好了。
    先用SQL语句创建表。再用VS.NET生成强类型的DataSet,窃笑不用写一句ADO.NET代码就已经获得全部所需要的东西了,包括插入删除等等,还是强类型的。往数据库中添加新行也比想象中的简单。那么剩下的问题就很简单了,就是读取文本,并将其内容添加到DataRow中。
    因为是VS.NET生成强类型的DataSet,数据库中每一个表对应的DataTable都是由DataTable类派生而来,并且提供了强类型的添加新数据的方法。这似乎意味着必须要为每一个表写一个单独的读取文件、添加数据的方法,因为强类型意味着每一个表的参数类型和数目都是不一样的。这就代表要写很多类似的代码。
    我试图找到一个可以对所有Ensembl表都适用的读取文件、添加数据的方法。首先想到的就是如果程序能按要求自动类型转换就好了,因为从文本中读取的数据全是string,而表中的数据很多为int. 理想状况是能根据表名自动调用对应的添加方法和转型方法。但思考了很久,感觉除了用swich-case语句,没有什么更简单的好办法。因为孤陋寡闻,我也没有看到有关能根据用户的要求进行类型转换的技术文章。
    这样一下子陷入困境,因为我在对象浏览器中查看了下各个表的派生DataRow成员,都提供了强类型的可读写属性器,可以设置各个表字段的值。不过话又说回来,即使可以自动转型,又该如何确定掉用哪个DataRow的哪个属性呢?后来我甚至想干脆用swich-case语句算了。
    然而,当我回头查看DataRow基类的成员时,希望出现了。它提供了参数为string的索引器,而且返回值为object,这就是说我能用任何类型的数据来设置DataRow的字段值。而且,由于各个表的DataRow都派生自这个DataRow基类,程序可以在运行时进行动态绑定来判断实际是哪一个DataRow. 真是得来全不费功夫。
    编码。
    为了保存所读取的文件中的数据,我使用了StringCollection来保存表的列集,使用Dictionary<string, string>保存一行的数据,以列名作键。事实上,用Dictionary<string, string>未必是最好的选择,这里只是用一用泛型而已。用List<Dictionary<string, string>>表示行的集合,同样也是泛型。
    如何确定该把值添加到DataRow的哪一个列下面?DataTable基类提供了Columns属性,它包含了列(DataColumn)的集合。可以用DataColumn的ColumnName属性来获取列名,以它作键来找到对应Dictionary<string, string>的值,类似于这个样子:

 1                DataRow row = null;
 2                for (int i = 0; i < this.RowCount; i++)
 3                {
 4                    row = this.table.NewRow();
 5
 6                    foreach (DataColumn column in this.table.Columns)
 7                    {
 8                        row[column.ColumnName] = this.file[i][column.ColumnName];
 9                    }

10
11                    this.table.Rows.Add(row);
12                }

    其中的file表示文本中的数据,也就是List<Dictionary<string, string>>集合,我把它包装到一个类里面了。
    这样,一个很看似麻烦的问题居然用最基本的动态绑定技术解决了,在运行的时候,程序可以知道使用的是哪一个DataRow,从而把数据添加到相应的表中,再Update一下就可以了。
    在Main方法里,为了把数据添加到不同的表,我还是不得不写了一堆重复的代码,用以初始化不同的表和调用对应的Update方法。不知道有没有好的办法把这个也简化掉。
    绕了个大弯子,还是用最基本的技术解决了问题,是不是有点讽刺?毕竟还是对各个类的成员不是很清楚,所以很多很容易的东西却犯了老大的迷糊。而且我还借助的是VS.NET生成的DataSet,要是自己写,又该是多麻烦和困难的事啊。

posted on 2006-10-16 11:10  天蓝  阅读(310)  评论(0编辑  收藏  举报