程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> C語言 >> 關於C語言 >> 用C#獲取無限多級分類的實現

用C#獲取無限多級分類的實現

編輯:關於C語言

所做的小項目中需要多級分類, 試著學習實現多級分類。由於對存儲過程本身並不大熟悉,也不想借助於treevIEw,於是遞歸邏輯采用C#實現,配合數數據庫完成了多級分類的獲取方法。增加分類節點應該說是比較簡單的,此文暫略。

數據庫表:CategoryInfo

字段名           類型

ciID                  int                        //記錄序號,自增量

ciName         nvarchar(20)       //分類名

ciParent           int                       //父分類序號

ciLayer              int                      //所處的層次

ciDescription     nvarchar(200)   //對分類的描述

獲取子分類的存儲過程

CREATE  PROCEDURE [dbo].[category_getChild]
 @cName nvarchar(20)
AS
BEGIN
DECLARE @tmpID int
SELECT @tmpID=ciID FROM CategoryInfo
   WHERE RTRIM(ciName) = RTRIM(@cName)
if(@tmpID IS NOT NULL)
SELECT * FROM CategoryInfo
  WHERE ciParent = @tmpID
  ORDER BY ciLayer 
END

獲取子分類的函數

        public IList<CategoryInfo> GetChildCategorIEs(IList<CategoryInfo> cInfos,string cName)
        {
            SqlConnection con = new SqlConnection(connectionString);
            SqlCommand cmd = new SqlCommand("category_getChild", con);
            cmd.CommandType = CommandType.StoredProcedure;
            cmd.Parameters.Add(new SqlParameter(PARAM_CNAME, SqlDbType.NVarChar, 20));
            cmd.Parameters[PARAM_CNAME].Value = cName;

            IList<string> tmpNames = new List<string>();   //臨時存儲獲取的子
            try
            {
                con.Open();
                SqlDataReader reader = cmd.ExecuteReader();
                if (reader.HasRows)
                {                  
                    while (reader.Read())
                    {
                      
                        CategoryInfo cInfo = new CategoryInfo(
                            (int)reader["ciID"],
                            reader["ciName"].ToString(),
                            (int)reader["ciParent"],
                            (int)reader["ciNum"],
                            reader["ciDescription"].ToString(),
                            (int)reader["ciLayer"]
                            );
                        string tmpName = reader["ciName"].ToString();
                        cInfos.Add(cInfo);//添加獲取到的分類到cInfos
                        tmpNames.Add(tmpName);//添加獲取到的子分類名到tmpNames                                
                    }
                }
            }
            catch
            {
                throw new ApplicationException("獲取分類出錯!");
            }
            finally
            {
                con.Close();
            }
                foreach(string c in tmpNames)
                {                  
                    cInfos = GetChildCategorIEs(cInfos,c);    //遞歸運算。繼續獲取子分類         
                }

            return cInfos;
        }

說明:在該函數中,tmpNames如果換成是IList<CategoryInfo>,即它添加的元素與cInfos是一樣的時,如果要移除其中的一項,則cInfos中會同時移除一項。因為CategoryInfo是類,是引用類型的,而非值類型。所以tmpNames采用了string類型,以避免這個問題。

對上面這個函數直接調用還稍嫌麻煩,上層程序還需要建立一個IList<CategoryInfo>對象,因此可以增加一個函數來調用上面的函數。這樣,上層程序只需要提供分類名,以及是否包含本級分類兩個參數就可以了。

        //獲取子分類,其中布爾參數表示是否包含本級分類
        public IList<CategoryInfo> GetCategorIEs( string cName, bool IsIncludeSelf)
        {
            IList<CategoryInfo> cInfos = new List<CategoryInfo>();
            cInfos = GetChildCategorIEs(cInfos, cName);
            if (IsIncludeSelf == true)
            {               
                cInfos.Insert(0, GetByName(cName));//根據名字獲取分類,這個很簡單,本文略。
            }
            return cInfos;
        }
           

注意:采用這種方式時,WEB服務器獲取子分類時要在數據庫服務器之間有多次往返,降低了性能。采用存儲過程實現遞歸邏輯,直接返回子分類列表的方式應該有更好的性能,尤其是Web服務器與數據庫服務器不位於同一台服務器上時,更會受網絡影響。


  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved