优化类别树搜索的解决方案

时间:2010-08-14 10:57:49

标签: c# linq optimization asp.net-mvc-2 business-logic-toolkit

我正在创建某种拍卖应用程序,我必须决定这个问题最优化的方法是什么。我正在使用BL Toolkit作为我的OR Mapper(它有很好的Linq支持)和ASP.NET MVC 2.

背景


我有多个Category个动态创建的对象,它们作为此类的表示保存在我的数据库中:

class Category
{
    public int Id { get; set; }
    public int ParentId { get; set; }
    public string Name { get; set; }
}

现在,每个Category对象都可以关联多个InformatonClass对象,这些对象代表该类别中的单个信息,例如它是价格或颜色。这些类也由管理员动态创建并存储在数据库中。特定于一组类别。代表它的类看起来如下:

class InformationClass
{
    public int Id { get; set; }
    public InformationDataType InformationDataType { get; set; }
    public string Name { get; set; }
    public string Label { get; set; }
}

现在我有第三个表格代表他们之间的联接:

class CategoryInformation
{
    public int InformationClassId { get; set; }
    public int AuctionCategoryId { get; set; }
}

问题


现在的问题是我需要继承子类别中的所有类别InformationClass。例如,每个产品都有价格,所以我需要将此InformationClass仅添加到我的根类别。频率信息可以添加到基本CPU类别中,并且应该在AMD和英特尔类别中提供,这些类别将来自CPU类别。

我必须经常在我的应用程序中知道哪些InformationClass个对象与指定的Category有关。

所以这是我的问题。对于这个问题,最优化的解决方案是什么?我有一些想法,但我无法决定。

  1. 将所有类别从数据库加载到Application表并每次从这个地方获取它们 - 只要类别不会经常更改它将减少数据库请求的数量,但它仍然需要使用Linq进行树搜索-to-对象
  2. 发明(我不知道是否可能)一些花哨的Linq查询,它可以搜索树并获取所有信息类ID,而不会过多地压力数据库。
  3. 其他一些不错的想法?​​
  4. 我将感激每一个答案和想法。谢谢大家的建议。

2 个答案:

答案 0 :(得分:3)

听起来像是我曾经博客过的一个想法:

基本思想是:除了Category表之外,还有一个CategoryTC表,其中包含父子关系的传递闭包。它允许您快速有效地检索特定类别的所有祖先或后代类别的列表。博客文章解释了每次创建,删除新的类别或更改父子关系时,如何使传递闭包保持最新(每次最多两次查询)。

该帖子使用SQL来表达这个想法,但我相信你可以将它翻译成LINQ。

您没有在问题中指定InformationClass表如何链接到Category表,所以我必须假设您有一个CategoryInformation表,看起来像这样:

class CategoryInformation
{
    public int CategoryId { get; set; }
    public int InformationClassId { get; set; }
}

然后,您可以使用以下内容获取与特定类别关联的所有InformationClasses:

var categoryId = ...;
var infoClasses = db.CategoryInformation
    .Where(cinf => db.CategoryTC.Where(tc => tc.Descendant == categoryId)
                                .Any(tc => tc.Ancestor == cinf.CategoryId))
    .Select(cinf => db.InformationClass
                      .FirstOrDefault(ic => ic.Id == cinf.InformationClassId));

这有意义吗?有任何问题,请询问。

答案 1 :(得分:2)