遞歸調用是程序設計中一個非常重要的方法。此法簡單直觀,結構清晰,程序易讀,給我們編制程序和調試程序帶來很大的方面,但計算機的執行過程比較複雜,時空性能相對較差。這裏從一個分類查詢開始說起。要求根據一張產品表,裏面有產品的信息,還有產品編碼,產品的父級編碼,產品是否選中(邏輯刪除)。這裏是通過一個TreeView來實現的,選擇父節點就會選中相應的子節點,然後點擊確定,就表示添加此產品;如果只選擇子節點,那父節點不會自動選中,也可以添加產品信息。這裏要實現的分類查詢就是,只要選中子節點,那麼查找後,不管有沒有選中父節點,父節點都會相應的出現,並加以顏色區分。
由上圖可以看出,不管煤油有沒有選中,在分類查詢裏如果其子節點被選中了,它就會顯示出來。
實現過程如下:
首先,通過查找先找出所有相應的選中產品來,並放到DataTable中。
string strSql = "select 產品編碼,產品父級編碼,其他信息 from 產品表 where 標識選中 = 1";
DataTable dt = GetDataTable(strSql);
然後調用遞歸方法,找到子節點所有的父節點;大致程序如下:
foreach(DataRow dr in dt.Rows)
{
strBm += getSupId(dr["bm"].ToString()) + ",";
}
/// <summary>
/// 獲得父級編碼
/// </summary>
/// <param name="strSubId">子節點編碼</param>
private string getSupId(string strSubId)
{
string strSql = "select 產品父級編碼 from 產品表 where 產品編碼 = " + strSubId+ "";
DataTable dt = GetDataTable(strSql);
//如果父級節點爲空,它就是父級節點,返回它的編碼;否則的話,傳入它的編碼作爲父級節點繼續查找
if (dt.Rows[0][0].ToString() == "")
{
return strSubId;
}
else
{
//遞歸調用
return getSupId(dt.Rows[0][0].ToString());
}
}
其次,當找到所有的父節點後,再進行查找,找相應的子節點,因爲在分類查詢中只有二級結構,即不管樹結構中分的幾級,而在分類查找中只要求兩級。
strSql = "select 產品編碼,產品父級編碼,其他信息 from 產品表 where 產品編碼 in(" + strBM + ")";
DataTable dt = GetDataTable(strSql);
DataTable dtNew = null;
foreach(DataRow dr in dt.Rows)
{
dtNew.Rows.Add(dr.ItemArray);
//獲得子集編碼
getSubId(dr[產品編碼].ToString(),ref strSubId);
//
strSql = "select 產品編碼,產品父級編碼,其他信息 from 產品表 where 標識選中 = 1 and 產品編碼 in(" + strSubId+ ")";
//添加新DataTable中,此DataTable即爲最中所要實現的DataTable
dtNew.GetDataTable(strSql);
}
/// <summary>
/// 獲得子級編碼
/// </summary>
/// <param name="strSupId">父節點</param>
/// <param name="strSubId">子節點</param>
private void getSubId(string strSupId,ref string strSubId)
{
string strSql = "select 產品編碼 from 產品表 where 產品父級編碼 = " + strSupId + "";
DataTable dt = GetDataTable(strSql);
foreach(DataRow dr in dt.Rows)
{
if(dr[0].ToString() != "")
{
strSubId += dr[0].ToString() + ",";
//遞歸調用
getSubId(dr[0].ToString(),ref strSubId);
}
}
}
至此差不多實現了所需要的功能。但是執行速度確實慢了下來。除了使用遞歸算法使速度降下來的原因外,還有對父節點查找子節點getSubId方法的過程中,沒有過濾掉沒有標識的產品,而是在新添加到DataTable的過程中過濾掉的,這樣的話,可能一個產品會有很多個子節點,從而使速度降了下來。如果將過濾的地方改到getSubId方法中,速度是不是就會提高很多呢?但是這樣的話,我們所要求的功能是不是還能完好的實現呢?答案就是速度會提高,功能會打折扣。