【问题标题】:Linq to SQL Nested ObjectsLinq to SQL 嵌套对象
【发布时间】:2011-03-14 15:50:46
【问题描述】:

我有一个名为 Category 的对象,它有一个 Id、Name 和 OwnerId。然后我嵌套这些以创建子类别。如果一个类别有一个所有者 ID,那么它就是一个子类别。子类别的数量是无限的,但每个项目只能有 1 个父项。很简单。

我的问题是,我需要在加载后访问子类别。如何使用 Linq 获取拥有类别。我知道所有者 ID,但我不知道所有者可以有多少 lvls。

基本上,我正在寻找一种方法来获取 Id == X 的类别或子类别,但这可以存在于 6 个级别或更深的子类别中。

我试图避免每个子类别中的每个子类别出现循环......

【问题讨论】:

    标签: c# .net linq performance linq-to-sql


    【解决方案1】:

    this fogbugz 博客文章中解释了另一种存储/检索树层次结构的方法:

    原来有一个很酷 此问题的解决方案由 乔·塞尔科。而不是试图 维护一堆父母/孩子 整个数据库中的关系 -- 这将需要递归 SQL 查询来查找所有 一个节点的后代——我们标记每个 具有“左”和“右”值的情况 通过遍历树计算 深度优先,边走边算。一种 节点的“左”值在任何时候被设置 在遍历期间首次出现,并且 行走时设置“正确”值 将树备份到远离节点的位置。 图片可能更有意义:

    嵌套集 SQL 模型让我们可以添加 不牺牲案例层次结构 性能。

    这有什么帮助?现在我们只问 对于所有具有“左”值的情况 在 2 到 9 之间找到所有 B的后代在一个快速,索引 询问。 G的祖先由 要求“左”小于的节点 6(G自己的“左”)和“右”更大 超过 6. 适用于所有数据库。 大大提高性能—— 特别是在查询大 层次结构

    Here's another post 更详细。它是使用 Sqlphp 编写的,但我认为您可以了解它的要点并轻松地将 Linq 转换为 Sql。

    【讨论】:

      【解决方案2】:

      在 MS SQL 2005 及更高版本中,您可以创建递归查询。但是,在 LINQ to SQL 中,您不走运。如果不重构数据库中的数据,就无法在单个数据库调用中遍历树。

      但是...我能想到 1 种解决方法。当您能够将单个树(或树的一部分)的所有 Category 元素组合在一起时,您可以在单个语句中预加载整个树的该部分。之后,您将能够遍历树的该部分,而不会触发对数据库的新调用。它看起来像这样:

      // Load the category that will be used as starting point.
      var subCategory = db.Categories.Single(c => c.Id == 56);
      
      // Performance: Load the complete group in one go.
      var categories = (
          from category in db.Categories
          where category.GroupId == subCategory.GroupId
          select category)
          .ToArray();
      
      // Traverse the tree and get the top-most parent (if any).
      var parent = subCategory.GetParents().LastOrDefault();
      
      // Extension method to get the parents.
      public static IEnumerable<Category> GetParents(
          this Category category)
      {
          while (category.Parent != null)
          {
              // NOTE: cat.Parent will not cause a database call
              // when the Parent is already loaded by L2S.
              yield return cat.Parent;
              category = category.Parent;
          }
      }
      

      这当然只有在您能够将元素确定为一个组时才有效。此解决方案是否会更快还取决于组的大小。当您加载(并且不使用)的对象组非常大时,它实际上会减慢应用程序的速度。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2010-09-18
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多