带有自引用和嵌套菜单的TreeMenu

本文关键字:菜单 TreeMenu 嵌套 自引用 | 更新日期: 2023-09-27 18:01:39

我需要使用NHibernate创建一个TreeMenu

这是我想到的:

public class CategoryMap : ClassMap<Category>
{
    public CategoryMap()
    {
        Id(x => x.Id);
        Map(x => x.AppId);
        Map(x => x.Title);
        Map(x => x.MaxDepth).Default("3");
        Map(x => x.IsActive);
        References(x => x.Parent).LazyLoad().Column("ParentId");
        HasMany(x => x.ChildrenNodes)
            .LazyLoad()
            .KeyColumn("ParentId")
            .Cascade.All();
        Table("Category");
    }
}
public class Category : Node
{
    public virtual string AppId { get; set; }
    public override string Title { get; set; }
    public override int MaxDepth { get; set; }
    public virtual Category Parent { get; set; }
    public virtual IList<Category> ChildrenNodes { get; set; }
    public virtual bool IsActive { get; set; }
}
public abstract class Node
{
    public virtual long Id { get; set; }
    public abstract string Title { get; set; }
    public abstract int MaxDepth { get; set; }
}
下面是我的测试代码:
[Test]
    public void CreateTableInDb()
    {
        using (var db = new FileDatabase(DbFileLocation, true))
        {
            var categoryMenu = new Category
            {
                AppId = "1",
                MaxDepth = 3,
                IsActive = true,
                Title = "Services"
            };
            db.Create(categoryMenu);

            categoryMenu.ChildrenNodes = new List<Category>
            {
                new Category
                {
                    Title = "SubService-Level1",
                    Parent = categoryMenu,
                }
            };
            db.Update(categoryMenu);
        }
    }

当我查看正在创建的表时,我只有一行,ParentId列为空

我怎么能解决它,我做错了什么?

带有自引用和嵌套菜单的TreeMenu

  • 首先你会错过.Inverse()上的许多。它将保存并更新parentId两次
  • 所有集合应该是只读的。NHibernate会用跟踪和延迟加载集合来代替它们,而这些都是你要扔掉的。将代码更改为

    public class Category : Node
    {
        public Category()
        {
            // best practice so that nobody has to null check the collection
            ChildrenNodes = new List<Category>();
        }
        public virtual IList<Category> ChildrenNodes { get; private set; }
        public void Add(Category subcategory)
        {
            subcategory.Parent = this;
            ChildrenNodes.Add(subcategory);
        }
    }
    // in testcode
    categoryMenu.Add(new Category { Title = "SubService-Level1" });