在某一天忽然觉得用 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;
第二步: 创建实体关系映射(实体层)
新建解决方案 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