DataSet本地化数据的二表链接操作

1,首先要产生链接操作的表,如果这两个表在同一个数据库中我想应该直接用sql语句就可以了,没有必要先拿到本地再进行链接操作;如果不在同一个数据库中(比如excel的两个文件中,这两个文件就等价于两个数据库),那么只好从每个数据库中先把感兴趣的数据表提取出来,放到本地的datase中,让它们形成一个本地数据库

2,c#的datatable对象是不允许同时隶属于多个dataset的。所以要将一个datatable从一个dataset转移到另一个dataset需要一定的技巧。一方面可以利用clone或者copy方法产生一个完全相同的datatable对象,但是在数据表比较大的情况下,复制数据既浪费时间又浪费空间;另一方面我们可以舍弃一个不太感兴趣的dataset来支持我们感兴趣的dataset。下面就是具体的处理方法:

public DataTable GetTable(string pPath, string pSql, string pName)
{
            try
            {
                string sCon = "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=" + pPath + ";Extended Properties='Excel 8.0;'";
                DataSet sSet = new DataSet();
                OleDbDataAdapter sAdapter = new OleDbDataAdapter(pSql, sCon);
                sAdapter.Fill(sSet, pName);
                DataTable sTable = sSet.Tables[pName];
                sSet.Tables.Remove(pName);//必须移除,同一个table不能同时存在两个set中
                sSet.Dispose();
                return sTable;
               
            }
            catch (Exception e)
            {
                MessageBox.Show(e.Message);
                return null;
            }
}

3,将感兴趣的表加入dataset后就构造好了本地数据库了,下一步应该建立两表之间的链接了。首先c#中的表间关系被定义为父子关系或者主从关系,这里的父和主对应于sql中含主键的表,而子和从则对应sql中含外键的表。其次这里容易发生于首先中提到的相对应的两个问题,一个是指定为父键的列中不能有重复值,否则会抛出异常,这个在framework中是坚决不允许的;另一个是指定为父键的列如果因为过滤而不包括子键列中的某些值,这时也会抛出异常,这个可在framework中是可以变通解决的。下面是具体的处理方法:

sDataSet.Relations.Add(sRelationName, sBaseInfoTable.Columns["资源ID"], sMemberResTable.Columns["资源ID"], false);

第一个参数是关系的名称,方便以后引用;第二个是父键列,第三个是子键列,第四个指定为false可以解决父键列不能全部包含子键列的问题。

具体的链接查询方法有两种,一种是站在父表的立场上,通过遍历每一个行对象,调用行对象的GetChildrenRow(s)函数得到子表中的感兴趣信息;另一种是站在子表的立场上,通过遍历每一个行对象,调用行对象的GetParentRow(s)函数得到父表中的感兴趣信息。这里给出子表立场上的访问方法:

foreach (DataRow sRow in sDataSet.Tables[sName].Rows)
{
                    if (sRow["资源ID"].ToString() == "")
                    {
                        MessageBox.Show("共有:" + count + "个资源库");
                        break;
                    }

                    DataRow[] sParent = sRow.GetParentRows(sRelationName);
                    foreach (DataRow sProw in sParent)
                    {
                        ++count;
                        sWriter.WriteLine("<ResDbInfo>");

                        sWriter.Write("<ResId>"); sWriter.Write(sProw["资源ID"]); sWriter.WriteLine("</ResId>");
                        sWriter.Write("<IsConfiged>"); sWriter.Write("1"); sWriter.WriteLine("</IsConfiged>");
                        sWriter.Write("<IsHot>"); sWriter.Write("0"); sWriter.WriteLine("</IsHot>");

                        sWriter.Write("<ResSub>");
                        string sSub = "";
                        for (int i = 1; i <= 4; ++i)
                        {
                            if (sProw["所属分类" + i].ToString() != "")
                            {
                                sSub = sSub + sProw["所属分类" + i].ToString() + ",";
                            }
                        }
                        sWriter.Write(sSub.Trim(new char[] { ','}));
                        sWriter.WriteLine("</ResSub>");

                        sWriter.Write("<Name>"); sWriter.Write(sRow["资源名"].ToString().Replace("&", "&amp;")); sWriter.WriteLine("</Name>");//用成员馆信息表中的资源名称作为资源名
                        //sWriter.Write("<Name>"); sWriter.Write(sProw["显示标题"].ToString().Replace("&", "&amp;")); sWriter.WriteLine("</Name>");用基本信息表中的显示标题字段作为资源名
                        sWriter.Write("<Homepage>"); sWriter.Write(sRow["链接URL地址"].ToString().Replace("&", "&amp;")); sWriter.WriteLine("</Homepage>");

                        sWriter.Write("<Description>");
                        sWriter.Write(sProw["资源库介绍"].ToString().Replace("&", "&amp;"));
                        sWriter.WriteLine("</Description>");

                        sWriter.WriteLine("</ResDbInfo>");
                    }
}

发布了148 篇原创文章 · 获赞 8 · 访问量 21万+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章