Nhibernate 一对多 与 一对一
上来园子就看到些标题党,觉着气氛怪怪的,为什么不是专注在自己感兴趣的领域呢.
在开发过程中使用nhibernate的时候会遇到一对一与一对多的关系,这里记下来方便自己也方便别人查看,希望遇到同样问题的同学少走弯路,能把更多精力放在业务逻辑上,需要的同学自己采用,有建议可以提。
现在关系是这样的,用户基本表一张,里面存储着用户的一些基本信息;用户扩展表一张,里面存储着用户的扩展信息比如用户偏好,生日(这些至于为什么不是放在一起每个人有自己的想法),用户消费记录表一张记录了消费信息。第一步新建用户类如下:
1 public class User{ 2 public virtual Int32 Id{get;set;} 3 public virtual String UserToken{get;set;} 4 public virtual String UserName{get;set;} 5 public virtual String UserPwd {get;set;} 6 public virtual virtual ISet<UserCostHistory> UserCostHistory { get; set; } 7 public virtual UserExten UserExten { get; set; } 8 }
第二步新建用户扩展类如下(可能后期改过部分字段,大家主要参考配置就是了)
1 public class UserExten 2 { 3 public virtual Int32 Id { get; set; } 4 public virtual String UserImg { get; set; } 5 public virtual String TrueName { get; set; } 6 public virtual DateTime? UserBirthday { get; set; } 7 8 9 public User User { get; set; } 10 }
这里是用户扩展表,虽然是通过UserId 相关联,但是在字段里没有写UserId,只是在后面有一个user的属性。
第三步新建用户消费表如下:
1 using System; 2 3 namespace Beauty.Core.Model 4 { 5 [Serializable] 6 public class UserCostHistory 7 { 8 public virtual Int32 Id { get; set; } 9 /// <summary> 10 /// 用户Token 11 /// </summary> 12 public virtual String UToken { get; set; } 13 /// <summary> 14 /// 订单编号 15 /// </summary> 16 public virtual String OrderNumber { get; set; } 17 /// <summary> 18 /// 店铺TOKEN 19 /// </summary> 20 public virtual String ShopToken { get; set; } 21 /// <summary> 22 /// 消费金额 23 /// </summary> 24 public virtual Decimal Cost { get; set; } 25 26 /// <summary> 27 /// 消费时间 28 /// </summary> 29 public virtual DateTime CostOn { get; set; } 30 /// <summary> 31 /// 备注 32 /// </summary> 33 public virtual String Note { get; set; } 34 public virtual User User { get; set; } 35 } 36 }
这里是用户消费表,表建到这里就完了,这里存在着一对多与一对一的关系,每个用户都包含着扩展的信息,每个用户有一条或者多条消费信息。在nhibernate 中应该怎么配置呢,请看如下配置,第一个是用户的
1 <?xml version="1.0" encoding="utf-8" ?> 2 <hibernate-mapping xmlns="urn:nhibernate-mapping-2.2" assembly="Beauty.Core" namespace="Beauty.Core.Model"> 3 4 <class name="User" table="`User`" lazy="false" > 5 <cache usage="read-write"/> 6 <id name="Id" column="Id" type="Int32"> 7 <generator class="identity"/> 8 </id> 9 <property name="Token" length="50" type="String" column="Token" /> 10 <property name="UName" length="50" type="String" column="UName" /> 11 <property name="UPwd" length="50" type="String" column="UPwd"/> 12 <property name="CreateOn" column="CreateOn" /> 13 <property name="CategoryId" type="Int32" column="CategoryId" /> 14 <property name="TrueName" type="String" length="20" column="TrueName" /> 15 <property name="ShopId" type="Int32" column="ShopId" /> 16 <property name="CardId" type="String" column="CardId" length="20" /> 17 18 <property name="UserNumber" type="String" column="UserNumber" length="20" /> 19 <property name="UserIntegral" type="Int32" column="UserIntegral" /> 20 <property name="UserLevel" type="Int32" column="UserLevel" /> 21 <property name="Amount" type="Decimal" column="Amount" /> 22 <property name="Sex" type="Int32" column="Sex" /> 23 24 <property name="Logins" type="Int32" column="Logins" /> 25 <property name="Email" type="String" column="Email" length="20" /> 26 <property name="UTel" type="String" column="UTel" length="20" /> 27 28 <set name="UserCostHistory" inverse="false" lazy="false" cascade="all" > 29 <key column="User_Id"> 30 31 </key> 32 <one-to-many class="UserCostHistory" /> 33 </set> 34 35 <one-to-one property-ref="User" class="UserExten" name="UserExten" cascade="all" lazy="false" constrained="true" > 36 37 </one-to-one> 38 </class> 39 </hibernate-mapping>
这里的one-to-one 就是一对一的配置关键了,roperty-ref 是主体,class="UserExten"是指一对一的那个类,重要的就是这两个,后面的几个属性百度一下大把的可以自己研究
<set name="UserCostHistory" inverse="false" lazy="false" cascade="all" >
<key column="User_Id">
</key>
<one-to-many class="UserCostHistory" />
</set>
这里是一对多的配置,inverse="false"这个配置很重要,少了可能会有错误,当时是个什么错误我也记不得了重现也不大现实。column 是关联的列,one-to-many class 这个就类名,因为我写的时候为了方便团队成员查看所以类名与表名一致,set的用法可以百度下这里主要是讲其配置,上面是user的下面要说的是扩展与消费的配置,扩展的配置如下:
1 <?xml version="1.0" encoding="utf-8" ?> 2 <hibernate-mapping xmlns="urn:nhibernate-mapping-2.2" assembly="Beauty.Core" namespace="Beauty.Core.Model"> 3 4 <class name="UserExten" table="UserExten" lazy="false" > 5 <cache usage="read-write"/> 6 <id name="Id" column="Id" type="Int32"> 7 <generator class="identity"/> 8 </id> 9 <property name="UserImg" column="UserImg" /> 10 <property name="TrueName" column="TrueName" /> 11 <property name="UserBirthday" column="UserBirthday" /> 12 13 14 <many-to-one name="User" class="User" column="User_Id" unique="true" cascade="all"/> 15 16 </class> 17 </hibernate-mapping>
这里没什么特殊的就是一个many to one 的标签与user对应,column 是对应的关联字段 unique 是限制只有一条的一个属性,因为其实是一个特殊的一对多,因为多的那个唯一了就成了一对一了。最后是用户消费的配置:
<?xml version="1.0" encoding="utf-8" ?> <hibernate-mapping xmlns="urn:nhibernate-mapping-2.2" assembly="Beauty.Core" namespace="Beauty.Core.Model"> <class name="UserCostHistory" table="UserCostHistory" lazy="false" > <cache usage="read-write"/> <id name="Id" column="Id" type="Int32"> <generator class="identity"/> </id> <property name="CostTime" column="CostTime"> </property> <property name="Amount" column="Amount" /> <many-to-one name="User" class="User" column="User_Id" cascade="all" /> </class> </hibernate-mapping>
这里也是最后那个一对多的标记,与一对一的不同之处就是unique,前面也说过了一对一就是一个特殊的一对多的关系而已,看的时候要联系起来看。这个配置完成后数据库里会自己产生外键关联,请大家自己参考,到此结束,有什么问题可以说说大家一起探讨。
郑重声明:本站内容如果来自互联网及其他传播媒体,其版权均属原媒体及文章作者所有。转载目的在于传递更多信息及用于网络分享,并不代表本站赞同其观点和对其真实性负责,也不构成任何其他建议。