在我们做网站的时候,不管是新闻系统还是产品系统,或者是博客,论坛等等,都少不了与分类打交道。有时候我们经常说分几级分类,一般分2-3级,具体视情况而定,但是这样的做法非常死板,不够灵活,因为不是任何类别下的分类都有子类,孙类……,为了能够使分类灵活,我们经常采用的是无限级分类。
无限级分类主要思路有两种:一是使用递归;二就是非递归,我比较喜欢这种,毕竟效率是关键。
表结构设计:
首先建立一个分类表Category:
设计如下:
--ParentID 父节点的ID
--CategoryPath 节点路径
--CategoryName 类别名称
--CategoryLevel 类别级别(主要为了操作方便才设置此字段)
--CategoryDescn 这个是类别描述,没啥好说的了,主要做搜索优化的时候用到,填充mata关键字
数据显示如下(仅仅是个例子,现实中可能不这么分):
水果--包括苹果,橘子;
苹果又分为红富士和乔纳金两个品种;
乔纳金又分为山东和北京的乔纳金;
山东乔纳金又分为济南乔纳金……
[图2]
产品表Product:
--CategoryID没啥好说的,主要是作为Category表的外键,注意有Categorypath这个字段的用意。
想实现的功能:
1.某一个类别下的子类
比方说水果这个类下,苹果,橘子着两个类。
select CategoryID,CategoryName from Category where ParentID=水果的CategoryID//由图2可以看到,ParentID为1的有苹果和橘子。
2.生成分类所在的路径,比方说 水果》苹果》乔纳金》山东乔纳金》济南乔纳金
主要思想是先得到当前类所对应的CategoryPath,然后把最后一个“,”去掉,foreach得到全路径
categoryPath = categoryPath.Substring(0, categoryPath.LastIndexOf(','));//得到CategoryPath
string arrCategory = categoryPath.Split(',');//以逗号分割
foreach (string s in arrCategory)
{
string classID = s.ToString();
if (classID == "0")//如果是0,代表这就是最高类
{
// 增加首页连接
HtmlAnchor lnkHome = new HtmlAnchor();
lnkHome.InnerText = "首页";
lnkHome.HRef = "~/Default.aspx";
plhControl.Controls.Add(lnkHome);
}
else
{
Category cg = new Category();
Xft.Model.Category cc = cg.GetModel(int.Parse(classID));
string categoryName = cc.CategoryName;
plhControl.Controls.Add(GetDivider());//增加一个分割线“》”
HtmlAnchor lnkCategory = new HtmlAnchor();//增加一个<a></a>元素
lnkCategory.InnerText = categoryName;
lnkCategory.HRef = string.Format(PRODUCTS_URL, classID);
plhControl.Controls.Add(lnkCategory);
}
}
3.得到任意分类下的所有产品信息:
得到该类别对应的CategoryPath,然后用下面sql语句查询即可
select * from Product where CategoryPath like '" + cpath + "%'
未解决的问题:如何判断一个类是否是这个分支的最末级类?比方说水果》橘子,橘子下面没有东西了,那么橘子这个类就是最末级分类,而苹果的末级分类是水果》苹果》乔纳金》山东乔纳金》济南乔纳金,有明白的大侠讲解一下,不胜感谢!