在某一天忽然觉得用 NHibernate 来实现无限级将会是多么简单,简单到你做梦都无法想到,似乎它天生就具备了处理这种情况的超能力。就连数据表的设计也被简化到了极致。
下面我会简单说明一下实现的步骤并给出源码下载,同时它也是 ASP.NET 2.0 + Spring.Net + Nhibernate + MYSQL 的一个实例,之所以使用了几个框架组合和 MYSQL 做为数据库,完全是出于自娱自乐,但我还是更希望大家把重点放在 NHibernate 实现无限级分类上。
第一步:创建数据库
--
创建数据库
CREATE DATABASE hibernatedemo;
-- 添加表 tb_Classes
DROP TABLE IF EXISTS `hibernatedemo`.`tb_classes`;
CREATE TABLE `hibernatedemo`.`tb_classes` (
`Id` int ( 10 ) unsigned NOT NULL DEFAULT ' 1 ' ,
`Name` varchar ( 45 ) NOT NULL ,
`ParentId` int ( 10 ) unsigned DEFAULT NULL ,
`SortOrder` int ( 10 ) unsigned NOT NULL DEFAULT ' 0 ' ,
PRIMARY KEY (`Id`),
KEY `tb_classes_ibfk_1` (`ParentId`),
CONSTRAINT `tb_classes_ibfk_1` FOREIGN KEY (`ParentId`) REFERENCES `tb_classes` (`Id`)
) ENGINE = InnoDB DEFAULT CHARSET = utf8;
CREATE DATABASE hibernatedemo;
-- 添加表 tb_Classes
DROP TABLE IF EXISTS `hibernatedemo`.`tb_classes`;
CREATE TABLE `hibernatedemo`.`tb_classes` (
`Id` int ( 10 ) unsigned NOT NULL DEFAULT ' 1 ' ,
`Name` varchar ( 45 ) NOT NULL ,
`ParentId` int ( 10 ) unsigned DEFAULT NULL ,
`SortOrder` int ( 10 ) unsigned NOT NULL DEFAULT ' 0 ' ,
PRIMARY KEY (`Id`),
KEY `tb_classes_ibfk_1` (`ParentId`),
CONSTRAINT `tb_classes_ibfk_1` FOREIGN KEY (`ParentId`) REFERENCES `tb_classes` (`Id`)
) ENGINE = InnoDB DEFAULT CHARSET = utf8;
第二步: 创建实体关系映射(实体层)
新建解决方案 NhibernateDemo,添加 ModelObject 项目用于存放实体类和映射文件。
创建 ClassesInfo.hbm.xml 文件 (CodeSmith 生成,需做修改)
<?xml version="1.0" encoding="utf-8" ?>
<hibernate-mapping xmlns="urn:nhibernate-mapping-2.0">
<class name="Yyw.ModelObject.ClassesInfo, Yyw.ModelObject" table="tb_classes">
<cache usage="read-write"/>
<id name="Id" type="Int32" unsaved-value="null">
<column name="Id" length="4" sql-type="int" not-null="true" unique="true" index="PK_tb_classes"/>
<generator class="Yyw.ModelObject.ClassesIdGenerator, Yyw.ModelObject" />
</id>
<property name="Name" type="String">
<column name="Name" length="45" sql-type="varchar" not-null="false"/>
</property>
<property name="SortOrder" type="Int32">
<column name="`SortOrder`" length="4" sql-type="int" not-null="true"/>
</property>
<many-to-one name="Parent" class="Yyw.ModelObject.ClassesInfo, Yyw.ModelObject" update="true" insert="true" cascade="delete-orphan">
<column name="ParentId" length="4" sql-type="int" not-null="false"/>
</many-to-one>
<bag name="Parenttb_classes" inverse="true" lazy="true" cascade="all-delete-orphan">
<key column="ParentId"/>
<one-to-many class="Yyw.ModelObject.ClassesInfo, Yyw.ModelObject"/>
</bag>
</class>
<query name="Yyw.ModelObject.ClassesInfo.Select.By.ParentId.Is.Null">
<![CDATA[
from ClassesInfo classesInfo where classesInfo.Parent.Id is null
]]>
</query>
</hibernate-mapping>
创建实体类 ClassesInfo.cs (CodeSmith 生成,需做修改)
using System;
using System.Collections;
using System.Web.UI.WebControls;
using System.Collections.Generic;
namespace Yyw.ModelObject
{
ClassesInfo#region ClassesInfo
/**//// <summary>
/// ClassesInfo object for NHibernate mapped table 'tb_classes'.
/// </summary>
public class ClassesInfo : System.IComparable
{
Member Variables#region Member Variables
protected int _id;
protected string _name;
protected int _sortOrder;
protected ClassesInfo _parent;
protected IList<ClassesInfo> _parenttbclasses;
protected static String _sortExpression = "Id";
protected static SortDirection _sortDirection = SortDirection.Ascending;
#endregion
Constructors#region Constructors
public ClassesInfo() { }
public ClassesInfo(string name, int sortOrder, ClassesInfo parent)
{
this._name = name;
this._sortOrder = sortOrder;
this._parent = parent;
}
#endregion
Public Properties#region Public Properties
public virtual int Id
{
get { return _id; }
set { _id = value; }
}
public virtual string Name
{
get { return _name; }
set
{
if ( value != null && value.Length > 45)
throw new ArgumentOutOfRangeException("Invalid value for Name", value, value.ToString());
_name = value;
}
}
public virtual int SortOrder
{
get { return _sortOrder; }
set { _sortOrder = value; }
}
public virtual ClassesInfo Parent
{
get { return _parent; }
set { _parent = value; }
}
public virtual IList<ClassesInfo> Parenttb_classes
{
get { return _parenttbclasses; }
set { _parenttbclasses = value; }
}
public static String SortExpression