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("&", "&")); sWriter.WriteLine("</Name>");//用成員館信息表中的資源名稱作爲資源名
//sWriter.Write("<Name>"); sWriter.Write(sProw["顯示標題"].ToString().Replace("&", "&")); sWriter.WriteLine("</Name>");用基本信息表中的顯示標題字段作爲資源名
sWriter.Write("<Homepage>"); sWriter.Write(sRow["鏈接URL地址"].ToString().Replace("&", "&")); sWriter.WriteLine("</Homepage>");
sWriter.Write("<Description>");
sWriter.Write(sProw["資源庫介紹"].ToString().Replace("&", "&"));
sWriter.WriteLine("</Description>");
sWriter.WriteLine("</ResDbInfo>");
}
}