NHibernate支持树形结构的解决方法

在实际项目中,经常会碰到树状结构,比如模块菜单,组织架构等,典型的定义如下图:

http://blogs.hibernatingrhinos.com/nhibernate/archive/2008/05/14/how-to-map-a-tree-in-nhibernate.aspx

对Nhibernate的tree map方法讲的比较详细,但是这种方法对于大数据量会有性能问题。我们更多的是用单表映射来完成实体类和表的一对一映射,如表

 

 image

 

对于这种树状结构的表,实体类一般都需要有HasChild活着ChildCount属性来表示是否是叶子节点,NHibernate可以用下面的映射文件来实现。

 

<?xml version="1.0" encoding="utf-8" ?>
<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2" >
  <!-- 菜单定义 -->
  <class name="SysAdmin.BLL.Domain.Menu,SysAdmin.BLL" table="SYSMENU" lazy="false">
    <!-- 主键 -->
    <id name="ID" column="ID">
      <generator class="Sys.Core.DAO.IDGenerator,Sys.Core">
        <param name="code">SYSPERMISSION.ID</param>
      </generator>
    </id>

    <!--菜单名 -->
    <property name="Name" column="NAME" />

    <!--菜单父id-->
    <property name="ParentId" column="PARENTID" />

    <!--<many-to-one name="Parent" class="SysAdmin.BLL.Domain.Menu,SysAdmin.BLL" column="PARENTID" />-->


    <!--菜单url-->
    <property name="Url" column="URL" />

    <!--JS 函数-->
    <property name="JsFunc" column="JSFUNC" />

    <property name="ChildCount" formula=""/>

  </class>
</hibernate-mapping>

 

实体类为:

/// 
namespace SysAdmin.BLL.Domain
{
    /// <summary>
    /// 菜单定义类
    /// </summary>
    public class Menu : DomainObject<Int32>
    {
        /// <summary>
        /// 菜单名
        /// </summary>
        public string Name { get; set; }

        /// <summary>
        /// 父菜单节点
        /// </summary>
        public Int32 ParentId { get; set; }

        /// <summary>
        /// 菜单url
        /// </summary>
        public string Url { get; set;}

        /// <summary>
        /// 触发的js函数
        /// </summary>
        public string JsFunc { get; set;}

        public Int32 ChildCount { get; set; }
        
        public override int GetHashCode()
        {
            return (GetType().FullName + ID).GetHashCode();
        }
    }
}
 
 
    
 
namespace SysAdmin.Test.DAO
{
    [TestFixture]
    public class MenuDAOTests : AbstractDaoIntegrationTests
    {
        public IMenuDAO MenuDAO { get; set; }

        public ISessionFactory SessionFactory { get; set; }

        [Test]
        public void TestAddMenu()
        {
            Menu menu = new Menu();
            menu.Name = "系统管理";
            //menu.ParentId = -1;
            menu.Url = "";
            menu.JsFunc = "";

            Int32 pMenuIdRoot = (Int32)MenuDAO.Save(menu);
            SessionFactoryUtils.GetSession(SessionFactory, true).Flush();

            menu = new Menu();
            menu.Name = "用户管理";
            menu.ParentId = pMenuIdRoot;
            MenuDAO.Save(menu);
            SessionFactoryUtils.GetSession(SessionFactory, true).Flush();

            menu = new Menu();
            menu.Name = "角色管理";
            menu.ParentId = pMenuIdRoot;
            MenuDAO.Save(menu);
            SessionFactoryUtils.GetSession(SessionFactory, true).Flush();

            menu = new Menu();
            menu.Name = "组织架构";
            menu.ParentId = pMenuIdRoot;
            MenuDAO.Save(menu);
            SessionFactoryUtils.GetSession(SessionFactory, true).Flush();

            menu = new Menu();
            menu.Name = "权限管理";
            menu.ParentId = pMenuIdRoot;
            Int32 pMenuId = (Int32)MenuDAO.Save(menu);
            SessionFactoryUtils.GetSession(SessionFactory, true).Flush();

            menu = new Menu();
            menu.Name = "菜单权限";
            menu.ParentId = pMenuId;
            MenuDAO.Save(menu);
            SessionFactoryUtils.GetSession(SessionFactory, true).Flush();

            menu = new Menu();
            menu.Name = "功能权限";
            menu.ParentId = pMenuId;
            MenuDAO.Save(menu);

            SessionFactoryUtils.GetSession(SessionFactory, true).Flush();

            //清理1级缓存,不清理不会触发select sql
            SessionFactoryUtils.GetSession(SessionFactory, true).Clear();

            menu = MenuDAO.FindById(pMenuIdRoot);

            SessionFactoryUtils.GetSession(SessionFactory, true).Flush();

            Assert.AreEqual("系统管理",menu.Name);
            Assert.AreEqual(4, menu.ChildCount );

            menu = MenuDAO.FindById(pMenuId);
            Assert.AreEqual("权限管理",menu.Name);
            Assert.AreEqual( 2,menu.ChildCount);
        }
    }
}
 
 

转载于:https://www.cnblogs.com/seman/archive/2009/09/22/1572175.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值