广

ASP.NET

  • IOS开发
  • android开发
  • PHP编程
  • JavaScript
  • ASP.NET
  • ASP编程
  • JSP编程
  • Java编程
  • 易语言
  • Ruby编程
  • Perl编程
  • AJAX
  • 正则表达式
  • C语言
  • 编程开发

    C# 无限级分类的实现

    2018-05-16 07:53:47 次阅读 稿源:互联网
    广告
    数据库表: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服务器与数据库服务器不位于同一台服务器上时,更会受网络影响。

    一起学吧部分文章转载自互联网,供读者交流和学习,若有涉及作者版权等问题请及时与我们联系,以便更正、删除或按规定办理。感谢所有提供资讯的网站,欢迎各类媒体与一起学吧进行文章共享合作。

    广告
    广告
    广告