数据库表:CategoryInfo 
字段名 类型 
ciID int //记录序号,自增量 
ciName nvarchar(20) //分类名 
ciParent int //父分类序号 
ciLayer int //所处的层次 
ciDescription nvarchar(200) //对分类的描述 
分类的类设计 
public class CategoryInfo 
{ 
private int ciID;//分类ID 
private string ciName;//分类名 
private int ciParent;//分类的父分类ID 
private string ciDescription;//分类描述 
private int ciLayer;//分类所属层次 
//构造函数 
public CategoryInfo() { } 
public CategoryInfo(int cID, string cName, int cParent, string cDescription, int cLayer) 
{ 
this.ciID = cID; 
this.ciName = cName; 
this.ciParent = cParent; 
this.ciDescription = cDescription; 
this.ciLayer = cLayer; 
} 
//属性 
public int CategoryID 
{ 
get{ return ciID;} 
set { ciID = value;} 
} 
public string CategoryName 
{ 
get{ return ciName;} 
set { ciName = value; } 
} 
public int CategoryParent 
{ 
get{ return ciParent;} 
set { ciParent = value; } 
} 
public string CategoryDescription 
{ 
get { return ciDescription; } 
set { ciDescription = value; } 
} 
public int CategoryLayer 
{ 
get { return ciLayer; } 
set { ciLayer = value; } 
} 
} 
获取子分类的存储过程 
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"], 
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服务器与数据库服务器不位于同一台服务器上时,更会受网络影响。
您可能感兴趣的文章:
