gpt4 book ai didi

c# - 需要一种算法来在 C# 中创建嵌套类别

转载 作者:太空狗 更新时间:2023-10-30 00:21:53 27 4
gpt4 key购买 nike

我的表结构如下:

categoryID bigint , primary key , not null
categoryName nvarchar(100)
parentID bigint, not null

其中 categoryID 和 parentID 彼此具有一对多关系

我想在我的程序中创建一个无限深度的嵌套类别。

我有一个解决方案,但效果不是很好,只返回根目录,请查看代码:

    private static string createlist(string catid, string parent)
{

string sql = "SELECT categoryID , categoryName FROM category WHERE parentID = " + parent;
SqlConnection cn = new SqlConnection(@"Data Source=.\SQLEXPRESS;Initial Catalog=sanjab;Integrated Security=True");
cn.Open();
SqlCommand cmd = new SqlCommand(sql, cn);
SqlDataReader sdr = cmd.ExecuteReader();

while (sdr.Read())
{
if (catid != "")
catid += ", ";
catid += sdr[1].ToString();
createlist(catid, sdr[0].ToString());


}
return catid;
}

虽然代码不是很有效,因为它同时打开了很多连接,但是在上面代码的帮助下和一点点调整我可以管理 2 级深度类别,但更多意味着很多麻烦对我来说。

有没有更简单的方法或算法?

问候。

最佳答案

假设您想要一次处理整个类别层次结构对象图,并且假设您正在处理合理数量的类别(故意强调),您最好的选择可能是一次性从 SQL 数据库加载所有数据,然后在内存中构建树对象图,而不是为树中的每个节点访问数据库,这可能会导致数百次数据库查找。

例如,如果有 5 个类别,每个类别有 5 个子类别,每个子类别有 5 个子子类别,您正在查看 31 个数据库命中,使用递归从数据库点加载它-当然,即使您只处理 125 条实际数据库记录。一次性选择所有 125 条记录不会耗尽资源,而 31 条以上的数据库命中可能会耗尽资源。

为此,我首先会以扁平化列表的形式返回您的类别(伪代码):

public IList<FlattenedCategory> GetFlattenedCategories()
{
string sql = "SELECT categoryID, categoryName, parentID FROM category";
SqlConnection cn = // open connection dataReader etc. (snip)

while (sdr.Read())
{
FlattenedCategory cat = new FlattenedCategory();
// fill in props, add the 'flattenedCategories' collection (snip)
}

return flattenedCategories;
}

FlattenedCategory 类会像这样查找:

public class FlattenedCategory
{
public int CategoryId { get; set; }
public string Name { get; set; }
public int? ParentId { get; set; }
}

现在我们有了所有类别的内存集合,我们像这样构建树:

public IList<Category> GetCategoryTreeFromFlattenedCollection(
IList<FlattenedCategory> flattenedCats, int? parentId)
{
List<Category> cats = new List<Category>();

var filteredFlatCats = flattenedCats.Where(fc => fc.ParentId == parentId);

foreach (FlattenedCategory flattenedCat in filteredFlatCats)
{
Category cat = new Category();
cat.CategoryId = flattenedCat.CategoryId;
cat.Name = flattenedCat.Name;

Ilist<Category> childCats = GetCategoryTreeFromFlattenedCollection(
flattenedCats, flattenedCat.CategoryId);

cat.Children.AddRange(childCats);

foreach (Category childCat in childCats)
{
childCat.Parent = cat;
}

cats.Add(cat);
}

return cats;
}

然后这样调用它:

IList<FlattenedCategory> flattenedCats = GetFlattenedCategories();
Ilist<Category> categoryTree = GetCategoryTreeFromFlattenedCollection(flattenedCats, null);

注意:在此示例中,我们为 ParentCategoryId 使用 Nullable INT,可为 null 的值表示它是根(顶级)类别(无父类别)。我建议您也将数据库中的 parentID 字段设置为可空。

警告:代码未经测试,只是伪代码,因此使用风险自负。这只是为了演示一般的想法。

关于c# - 需要一种算法来在 C# 中创建嵌套类别,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3455895/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com