NHibernate学习过程笔记

NHbernate自动生成数据库的方法:

using NHibernate;
using NHibernate.Tool.hbm2ddl;

namespace Test
{
  public  class NHDataProvier
  {
      private readonly ISessionFactory _sessionFactory;
      public NHDataProvier()
      {
          var configuration = new NHibernate.Cfg.Configuration();
          configuration.Configure();
          _sessionFactory = configuration.BuildSessionFactory();
      }

      public void InitDb()
      {
          var configuration = new NHibernate.Cfg.Configuration();
          configuration.Configure();
         
          new SchemaUpdate(configuration).Execute(true,true);
         
       
      }
  }
}
NHDataProvier

 NHbernate映射的一些总结:

普通的映射很简单,网上资料也比较多,比较全,我参考的是:http://www.cnblogs.com/GoodHelper/tag/NHibernate/

写的挺不错,大家可以参考一下。

NHbernate中的继承映射:

NHbernate中继承映射的方法常用的有三种:

1.单表继承:即所有父类及子类的字段都放在一个表中,用一个字段来区分子类,但是个人觉得这种方式中是依靠某些特殊的字段是否为空来区别子类的,很多字段的值都会为空,因此不太可取。

2.类表映射:类表映射,故名思议就是一个子类一个表,其子类表通过外键关联到主表。然后一个子类对应一张表。

映射文件如下:

 1 <?xml version="1.0" encoding="utf-8" ?>
 2 <hibernate-mapping xmlns="urn:nhibernate-mapping-2.2">
 3   <class name="Model.AnimalModel,Model" table="Animal"> <!--去掉discriminator-value,类表映射这个属性没用了-->
 4     <id name="AnimalId" column="AnimalId" type="Int32">
 5       <generator  class="native"/>
 6     </id>
 7     <discriminator column="AnimalType" type="String" />
 8     <property name="Name" column="Name" type="String"/>
 9     <joined-subclass extends="Model.AnimalModel, Model" name="Model.FrogModel, Model" table="Frog"> <!--增加表名-->
10       <key column="Id"/>  <!--添加主键Id-->
11       <property name="Foot" column="Foot" type="String"/>
12     </joined-subclass>    <!--joined-subclass-->
13   </class>
14 </hibernate-mapping>
Animal.hbm.xml
1 <?xml version="1.0" encoding="utf-8" ?>
2 <hibernate-mapping xmlns="urn:nhibernate-mapping-2.2" default-lazy="false">
3   <joined-subclass extends="Model.AnimalModel, Model" name="Model.FishModel, Model" table="Fish"> 
4       <key column="Id"/>
5       <property name="Tail" column="Tail" type="String"/>
6     </joined-subclass>
7 </hibernate-mapping>
Fish.hbm.xml

当然,也可以把Animal.hbm.xml中子类的映射单独写出来而不写在父类的映射中,只需指定extends即可。

3.类表映射使用Discriminator

我在实际使用中用到的就是这种映射方式,Demo如下:

项目的类图如下:

NewsMessage和TextMessage均继承字MessageBase这样一个抽象的父类,父类实现了IMessageBase这样一个接口,方便调用时强转。

映射文件如下:

<?xml version="1.0" encoding="utf-8" ?>
<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2" assembly="YLXY.Weixin.Model"
                   namespace="YLXY.Weixin.Model.Message" default-lazy="true">


  <!--MessageBase映射-->
  <class name="MessageBase" table="MessageBase" discriminator-value="Message">
    <id name="Id" column="Id" type="Guid">
      <generator class="assigned">
      </generator>
    </id>
    <discriminator  type="String" column="MsgType"></discriminator>
  </class>


  <!--NewsMessage映射-->
<subclass extends="MessageBase" name="NewsMessage" discriminator-value="News">
    <join table="NewsMessage">
      <key column="Id"/>
    <bag name="Articles">
      <key column="ArticleId" not-null="true"/>
      <one-to-many class="Article"/>
    </bag>
    </join>
  </subclass>


  <!--Article映射-->
 <class name="Article" table="Article">
    <id name="Id" column="Id" type="Guid">
      <generator class="assigned">
      </generator>
    </id>
    <property name="Title" column="Title" type="String"></property>
    <property name="Description" column="Description" type="String"></property>
    <property name="PicUrl" column="PicUrl" type="String"></property>
    <property name="Url" column="Url" type="String"></property>
    <many-to-one name="NewsMessage" column="NewsMessageId" class="NewsMessage" />
    <many-to-one name="UserInfo"  class="YLXY.Weixin.Model.Permission.UserInfo,UserInfo"/>
  </class>


  <!--TextMessage映射-->
      
  <subclass extends="MessageBase" name="TextMessage"  discriminator-value="Text">
    <join table="TextMessage">
      <key column="Id"/>
      <property name="Content" column="Content" type="String"></property>
    </join>
  </subclass>
</hibernate-mapping>
Message.hbm.xml

业务中一个News中有多个Articles,大家无需关心。

在映射过程中,需要注意的是:

1.在MessageBase实体类中,不需要指定MessageType属性,只需在映射文件中指定就好了。

2.在MessageBase实体的映射文件中,务必指明辨别字段: <discriminator  type="String" column="MsgType"></discriminator>

3.在子类中,务必指明discriminator-value属性,并且各个子类的此属性不能重复,因为ORM最终是根据次属性来判断是哪个子类实体的,从而去不同的表中取对象。

如果在调试过程中报如下错误:

XML validation error: 元素 命名空间“urn:nhibernate-mapping-2.2”中的“class”。 的子元素 命名空间“urn:nhibernate-mapping-2.2”中的“discriminator”。 无效。

则很有可能是<discriminator  type="String" column="MsgType"></discriminator>与其它属性顺序的问题。请务必把辨别字段的映射写在其它所有字段映射的最前面。

先就总结这么多吧,菜鸟初写博客,有不足之处请多多批评指教。

原文地址:https://www.cnblogs.com/baiyunchen/p/3813447.html