今天做了第一个Nhibernate项目,摸着石头过河,学到了一些东西,在这里将自己总结体会到的一些映射关系写出来,与大家分享,由于是初学者,如果有不对的地方希望大家能够指出来。
首先要说明要建立的几张表:(CouponType表的CouponTypeID与Merchant表中的MerchantID是多对一的关系,CouponType表中的CouponTypeID与Product表中的ProductID是多对多的关系)
CouponType表:
字段属性 |
字段名称 |
类型 |
非空 |
备注 |
优惠券发放编号 |
CouponTypeID |
Int |
Not null |
主键、唯一性约束。自增长 |
优惠券类型名 |
Name |
Varchar(100) |
Not null |
|
...... |
...... |
...... |
....... |
|
面向商户 |
MerchantID |
Int |
Not null |
外键 |
Merchant表:
字段属性 |
字段名称 |
类型 |
非空 |
备注 |
商户编号 |
MerchantID |
Int |
Not null |
0为全部商户 |
商户名称 |
Name |
Varchar |
Not null |
|
商户描述 |
Description |
Varchar |
Not null |
|
Product表:
字段属性 |
字段名称 |
类型 |
非空 |
备注 |
商品编号 |
ProductID |
Int |
Not null |
主键 |
商品名称 |
Name |
Varchar |
Not null |
|
所属类 |
ProductCategoryID |
Int |
Not null |
外键 |
1、多对一的映射:
首先要定义CouponType表的实体类:
1 using System; 2 using System.Collections.Generic; 3 using System.Linq; 4 using System.Text; 5 6 namespace Giti.Domain 7 { 8 using Giti.Core; 9 using Iesi.Collections; 10 using Iesi.Collections.Generic; 11 12 public class CouponType : EntityBase 13 { 14 public virtual string CouponTypeName { get; set; } 15 16 .......... 17 18 public virtual Merchant Merchant { get; set; } 19 } 20 }
然后是CouponType.hbm.xml
1 <?xml version="1.0" encoding="utf-8" ?> 2 <hibernate-mapping xmlns="urn:nhibernate-mapping-2.2" 3 assembly="Giti.Domain" 4 namespace="Giti.Domain"> 5 6 <class name="CouponType" table="T_CouponType"> 7 <id name="Id"> 8 <generator class="native" /> 9 </id> 10 <version name="Version" /> 11 12 <property name="CouponTypeName" /> 13 .......... 14 <many-to-one name="Merchant" cascade="save-update"/> 15 .......... 18 19 <property name="SortIndex" /> //一下几行代码没有特殊规定,只是为了方便维护数据库表而添加。 20 <property name="Active" /> 21 <property name="CreateBy" update="false" /> 22 <property name="UpdateBy" /> 23 <property name="CreateDate" update="false" /> 24 <property name="LastUpdate" /> 25 </class> 26 </hibernate-mapping>
完成多对一的代码后,要马上去补充一对多的部分与之对应,详见2、一对多的映射
2、一对多的映射:
完成多对一的代码后要马上补充一对多的部分与之对应,
首先是Merchant实体类代码:
1 using System; 2 using System.Collections.Generic; 3 using System.Linq; 4 using System.Text; 5 6 namespace Giti.Domain 7 { 8 using Giti.Core; 9 using Iesi.Collections; 10 using Iesi.Collections.Generic; 11 12 public class Merchant : EntityBase 13 { 14 public virtual string Name { get; set; } 15 16 public virtual string Description { get; set; } 17 18 19 private ISet<CouponType> _couponTypes = new SortedSet<CouponType>(); 20 21 public virtual ISet<CouponType> CouponTypes 22 { 23 get { return _couponTypes; } 24 set { _couponTypes = value; } 25 } 26 27 28 } 29 30 }
然后看一下Merchant.hbm.xml的代码:
1 <?xml version="1.0" encoding="utf-8" ?> 2 <hibernate-mapping xmlns="urn:nhibernate-mapping-2.2" 3 assembly="Giti.Domain" 4 namespace="Giti.Domain"> 5 6 <class name="Merchant" table="T_Merchant"> 7 <id name="Id"> 8 <generator class="native" /> 9 </id> 10 <version name="Version" /> 11 12 <property name="Name" /> 13 <property name="Description" /> 14 15 <set name="CouponTypes" inverse="true" cascade="none" lazy="true"> 16 <key column="Merchant" /> 17 <one-to-many class="Giti.Domain.CouponType, Giti.Domain"/> 18 </set> 19 20 <property name="SortIndex" /> 21 <property name="Active" /> 22 <property name="CreateBy" update="false" /> 23 <property name="UpdateBy" /> 24 <property name="CreateDate" update="false" /> 25 <property name="LastUpdate" /> 26 </class> 27 </hibernate-mapping>
到此一组“多对一”和“一对多”的关系已经建立起来
3、多对多的映射(需要建表):
下面我们看一下多对多的关系,多对多的关系如果通过外键关联,则会造成数据库设计的不规范,所以当有多对多的关系出现时我们采用建一张关系表的方式来解决。
CouponType中CouponTypeID与Product中的ProductID是多对多的关系,所以要在上面CouponTyoe实体类的基础上添加一些关系(黄色底部分为添加代码),代码如下:
1 using System; 2 using System.Collections.Generic; 3 using System.Linq; 4 using System.Text; 5 6 namespace Giti.Domain 7 { 8 using Giti.Core; 9 using Iesi.Collections; 10 using Iesi.Collections.Generic; 11 12 public class CouponType : EntityBase 13 { 14 public virtual string CouponTypeName { get; set; } 15 16 ......... 17 18 public virtual Merchant Merchant { get; set; } 19 20 private ISet<Product> _products = new SortedSet<Product>(); 21 22 public virtual ISet<Product> Products 23 { 24 get { return _products; } 25 set { _products = value; } 26 } 27 } 28 }
CouponType.hbm.xml
1 <?xml version="1.0" encoding="utf-8" ?> 2 <hibernate-mapping xmlns="urn:nhibernate-mapping-2.2" 3 assembly="Giti.Domain" 4 namespace="Giti.Domain"> 5 6 <class name="CouponType" table="T_CouponType"> 7 <id name="Id"> 8 <generator class="native" /> 9 </id> 10 <version name="Version" /> 11 12 <property name="CouponTypeName" /> 13 ....... 14 <many-to-one name="Merchant" cascade="save-update"/> 15 20 21 <set name="Products" inverse="false" cascade="save-update" table="T_Coupon_Product"> 22 <key column="CouponTypeId" /> 23 <many-to-many column="ProductId" class="Giti.Domain.Product, Giti.Domain" /> 24 </set>
28 <property name="SortIndex" /> 29 <property name="Active" /> 30 <property name="CreateBy" update="false" /> 31 <property name="UpdateBy" /> 32 <property name="CreateDate" update="false" /> 33 <property name="LastUpdate" /> 34 </class> 35 </hibernate-mapping>
注意与之前代码不同,这里要建表!
然后就是Product的实体类和Product.hbm.xml
1 using System; 2 using System.Collections.Generic; 3 using System.Linq; 4 using System.Text; 5 6 namespace Giti.Domain 7 { 8 using Giti.Core; 9 using Iesi.Collections; 10 using Iesi.Collections.Generic; 11 12 public class Product:EntityBase 13 { 14 public virtual string Name { get; set; } 15 16 private ISet<CouponType> _couponTypes = new SortedSet<CouponType>(); 17 18 public virtual ISet<CouponType> CouponTypes 19 { 20 get { return _couponTypes; } 21 set { _couponTypes = value; } 22 } 23 } 24 }
1 <?xml version="1.0" encoding="utf-8" ?> 2 <hibernate-mapping xmlns="urn:nhibernate-mapping-2.2" 3 assembly="Giti.Domain" 4 namespace="Giti.Domain"> 5 6 <class name="Product" table="T_Product"> 7 <id name="Id"> 8 <generator class="native" /> 9 </id> 10 <version name="Version" /> 11 12 <property name="Name" /> 13 14 <set name="CouponTypes" inverse="false" cascade="save-update" table="T_Coupon_Product"> 15 <key column="ProductId" /> 16 <many-to-many column="CouponTypeId" class="Giti.Domain.CouponType, Giti.Domain" /> 17 </set> 18 <property name="SortIndex" /> 19 <property name="Active" /> 20 <property name="CreateBy" update="false" /> 21 <property name="UpdateBy" /> 22 <property name="CreateDate" update="false" /> 23 <property name="LastUpdate" /> 24 </class> 25 </hibernate-mapping>
到此三个映射关系已基本完成,在配置过程中我最大的感觉是映射关系配置要两两一起配置,这样思路会更清晰,配置过程也不容易出错。