一个比较高效的无限分类算法
无限分类是我们做网站经常遇到的问题,一般我们建一个自关联的表,用一个字段表示父节点,如下商品分类表:
我们做网站时,一般也是一级一级往下查看,没什么不方便的。
但是,如果是个地址分类呢?有可能给出某个地址,我们要得到它的路径。
有个位编码的算法可以解决上面的问题,可是实现起来有点麻烦,下面给出一种方法,相对比较简单,也容易实现,而且他们之间似乎有点相似之处。
建表:
添加了psrt字段,用来记录路径,路径中用“,”隔开,添加时只要将父节点的路径加上父节点表示即可。删除时加上where id=@id or pstr like ‘%,@id,%’,可删除全部子孙节点。获取路径 where id in (" + caddr.pstr.Trim(',')……
部分代码:
/// <summary>
/// 获取路径:父->子
/// </summary>
public List<Fz.Model.cityaddr> GetPath(int addrid)
{
Model.cityaddr caddr = GetModel(addrid);
if (!string.IsNullOrEmpty(caddr.pstr.Trim(',')))
{
return GetModelList("id in (" + caddr.pstr.Trim(',') + ") order by rank");
}else{
throw new Exception("没有父节点");
}
}
/// <summary>
/// 获取路径:父-子
/// </summary>
public string[] GetPathStr(int addrid)
{
List<Fz.Model.cityaddr> laddr = GetPath(addrid);
string[] ret = new string[laddr.Count];
for (int i = 0; i < laddr.Count;i++ )
{
if (!string.IsNullOrEmpty(laddr[i].city))
{
ret[i] = laddr[i].city;
}
}
return ret;
}
/// <summary>
/// 获取所有子节点
/// </summary>
public List<Fz.Model.cityaddr> GetAllSon(int addrid)
{
string strwhere ="pstr like '%,"+ addrid + ",%' order by rank";
return GetModelList(strwhere);
}
/// <summary>
/// 获取子节点
/// </summary>
public List<Fz.Model.cityaddr> GetSon(int addrid)
{
return GetModelList("pid="+addrid);
}
/// <summary>
/// 获取子节点,返回增加的项的d
/// </summary>
public int Add(int pid, string city)
{
Model.cityaddr ca = GetModel(pid);
if (ca == null)
{
ca = new Fz.Model.cityaddr();
ca.parentid = 0;
ca.pstr = ",";
ca.rank = 1;
}
else
{
ca.parentid = pid;
ca.pstr = ca.pstr + pid + ",";
ca.rank++;
}
ca.city = city;
return Add(ca);
}
/// 获取路径:父->子
/// </summary>
public List<Fz.Model.cityaddr> GetPath(int addrid)
{
Model.cityaddr caddr = GetModel(addrid);
if (!string.IsNullOrEmpty(caddr.pstr.Trim(',')))
{
return GetModelList("id in (" + caddr.pstr.Trim(',') + ") order by rank");
}else{
throw new Exception("没有父节点");
}
}
/// <summary>
/// 获取路径:父-子
/// </summary>
public string[] GetPathStr(int addrid)
{
List<Fz.Model.cityaddr> laddr = GetPath(addrid);
string[] ret = new string[laddr.Count];
for (int i = 0; i < laddr.Count;i++ )
{
if (!string.IsNullOrEmpty(laddr[i].city))
{
ret[i] = laddr[i].city;
}
}
return ret;
}
/// <summary>
/// 获取所有子节点
/// </summary>
public List<Fz.Model.cityaddr> GetAllSon(int addrid)
{
string strwhere ="pstr like '%,"+ addrid + ",%' order by rank";
return GetModelList(strwhere);
}
/// <summary>
/// 获取子节点
/// </summary>
public List<Fz.Model.cityaddr> GetSon(int addrid)
{
return GetModelList("pid="+addrid);
}
/// <summary>
/// 获取子节点,返回增加的项的d
/// </summary>
public int Add(int pid, string city)
{
Model.cityaddr ca = GetModel(pid);
if (ca == null)
{
ca = new Fz.Model.cityaddr();
ca.parentid = 0;
ca.pstr = ",";
ca.rank = 1;
}
else
{
ca.parentid = pid;
ca.pstr = ca.pstr + pid + ",";
ca.rank++;
}
ca.city = city;
return Add(ca);
}
浙公网安备 33010602011771号