具有较少查询的类别树的解决方案?

时间:2010-01-13 04:49:37

标签: asp.net-mvc linq-to-sql html-helper

基本上,模型是这样的:

----------------------------------
| CAT_ID | CAT_NAME | CAT_PARENT |
----------------------------------

这使得它成为一种递归关系。但是我们应该如何在我们的Asp.net mvc Web应用程序中使用此模型,并且查询量最少。我的临时解决方案是将对象传递给函数并让函数传递对象,而不是requerry,但这是我尝试的代码:

public string CategoryTree(this HtmlHelper html, IEnumerable<Category> categories, int? parent)
{
    parent = parent ?? 0;
    string htmlOutput = string.Empty;
    var cat = categories.Where(d => d.CAT_PARRENT == parent.Value);
    if (cat.Count() > 0)
    {
        htmlOutput += "<ul>";
        foreach (Category category in cat)
        {
            htmlOutput += "<li>";
            htmlOutput += category.CAT_NAME;
            htmlOutput += html.CategoryTree(categories, category.CAT_ID);
            htmlOutput += "</li>";
        }
        htmlOutput += "</ul>";
    }

    return htmlOutput;
}

但是这会为4行类别生成4个查询。所以这不是解决这个问题的好方法。我使用linq to sql。

1 个答案:

答案 0 :(得分:1)

不要忘记.Count()也可能生成查询;你可以使用Where()。ToList()然后使用它.Count,因为你还是要使用完整的集合。

替代方法是首先收集CAT_ID,获取所有的所有相关子项,然后将子项作为集合提示传递给您的方法。像Smth一样

public string CategoryTree(this HtmlHelper html, IEnumerable<Category> categories, IList<Category> cats)
{
      var query = categories.Where(x => false);
      // a query to select ALL new children
      foreach (var parent in cat.Select(x => x.CAT_ID))
            query = query.Union(categories.Where(x => x.CAT_PARENT = parent));
      var newchildren = query.ToList(); // execute query for all children at once - only once

      foreach (Category category in cats)
      {
            htmlOutput += "<li>";
            htmlOutput += category.CAT_NAME;
            // here we select only this category children - from already executed query results
            htmlOutput += html.CategoryTree(categories, newchildren.Where(x => x.CAT_PARENT = category.CAT_ID).ToList());
            htmlOutput += "</li>";
      }
}

当然这不是最终的代码,你最好使用IN [parentid,parentid,parentid]而不是UNION,但这就是主意。