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

时间:2013-02-27 20:40:36

标签: c# fluent-nhibernate fluent-nhibernate-mapping

我需要使用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列。

我如何解决它以及我做错了什么?

1 个答案:

答案 0 :(得分:0)

  • 首先你会遗漏.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" });