使用具有外部/导航键的Model类 - pt。 2

时间:2016-09-02 05:49:43

标签: c# jquery asp.net asp.net-mvc entity-framework

这与this问题有关。 (我没有必要的声誉来发表评论)

假设我们有相同的模型类

public class Category
{
   public int CategoryID { get; set; }
   public string CategoryName { get; set; }
   public int? ParentCategoryID { get; set; }
   public string CategoryDesc { get; set; }

   [ForeignKey("ParentCategoryID")]
   public virtual Category ParentCategory { get; set; }

   [InverseProperty("ParentCategory")]
   public virtual ICollection<Category> SubCategories{ get; set; }

   public virtual ICollection<Product> Products { get; set; }
}

并使用此查询

var topCategories = dbStore.Categories.ToList().Where(category => category.ParentCategoryID == null);

组织和使用收藏集topCategories的最佳做法是什么?

我有类似的情况,在我的情况下,SubCategories可能是7或8级深,我需要知道每个Category在层次结构中的位置,以便从中构建一个视图数据。

我正在使用jQuery treetable,并且它要求所有内容都按层次结构顺序排列,并且要为每个id引用其父级<tr>以便可折叠树到工作

我相信我可以通过在构建ViewModel并返回View的方法中为层次结构的每个级别创建单独的变量(通过在topCategories上运行查询并为每个级别创建单独的集合)来完成此工作。 ,但我很想知道是否有更干净/更优雅的方式来做到这一点。

由于

1 个答案:

答案 0 :(得分:0)

我在this post找到了我想要做的解决方案。

我确信我没有以足够明确的方式提出原始问题,但是想补充一下这个问题,以防其他任何人因为这个问题而陷入困境。

我仍然有一些阅读要做,因为我并不完全理解所有这些,但我最终要找的是topological sort,如上面链接的SO帖子所述。

以下是为此帖子编辑的参考帖子中的代码。

如果有人愿意介绍这里发生的一切,我将非常感激。

class FlattenTree
{
  // map each item to its children
  ILookup<Category, Category> mapping;

  public FlattenTree(IEnumerable<Category> list)
  {
    var itemLookup = list.ToDictionary(item => item.ID);
    mapping = list.Where(i => i.ParentCategoryID.HasValue)
                  .ToLookup(i => itemLookup[i.ParentCategoryID.Value]);
  }

  IEnumerable<Item> YieldItemAndChildren(Item node)
  {
    yield return node;
    foreach (var child in mapping[node].OrderBy(i => i.CategoryName))
        foreach (var grandchild in YieldItemAndChildren(child))
            yield return grandchild;
  }

  public IEnumerable<Category> Sort()
  {
    return from grouping in mapping
           let item = grouping.Key
           where item.ParentCategoryID == null
           orderby item.CategoryName
           from child in YieldItemAndChildren(item)
           select child;
  }
}