找回密码
 立即注册
首页 业界区 业界 NHibernate2.1新特性之entity-name

NHibernate2.1新特性之entity-name

赏勿 2025-5-29 15:01:30
本节内容
           
  • 概览       
  • 典型实例
                     
    • 1.Domain               
    • 2.Mapping               
    • 3.Test       
           
  • 代码       
  • 结语       
  • 参考资料
概览

接着完成以前的NHibernate2.1新特性系列文章(NHibernate2.1新特性之Tuplizers、NHibernate2.1新特性之EntityMode.Map),这个系列主要摘取一些最新的例子来展示NHibernate2.1的新特性,等这个系列完成再准备另外一个新系列吧,因为关于NHibernate2.1的介绍还没有。这篇文章看看NHibernate2.1另外的一个新特性——实体名称(entity-name)。
实体名称(entity-name)在Class的Mapping中使用,一般而言,我们并不特意定义它,只有在其Class的Name的属性有点复杂的时候使用一个别名。在保存Domain的时候,ISession.Save()也有重载方法。
典型实例

这个实例使用继承映射,对于子类的名称比较复杂,我们可以使用entity-name来重新定义它的名称。
1.Domain
  1. public abstract class Animal
  2. {
  3.     public virtual int Id { get; private set; }
  4.     public virtual string Description { get; set; }
  5. }
  6. public class Reptile : Animal
  7. {
  8.     public virtual float BodyTemperature { get; set; }
  9. }
  10. public class Human : Animal
  11. {
  12.     public virtual string Name { get; set; }
  13.     public virtual string NickName { get; set; }
  14.     public virtual DateTime Birthdate { get; set; }
  15. }
  16. public class Family<T> where T : Animal
  17. {
  18.     public virtual int Id { get; private set; }
  19.     public virtual T Father { get; set; }
  20.     public virtual T Mother { get; set; }
  21.     public virtual ISet<T> Childs { get; set; }
  22. }
复制代码
2.Mapping

在数据库中我想每个Animal使用不同的表,所以需要三个不同的表。当然,所有"Kinds"的家庭只有一个表可能不够,因为我不可能有一个ForeignKey指向两个表。我需要一个表有强类型Family。使用NHibernate新的标签:实体名称(entity-name)可以做到。
  1. <class name="Animal">
  2.     <id name="Id" column="animalId">
  3.         <generator class="hilo"/>
  4.     </id>
  5.     <property name="Description"/>
  6.     <joined-subclass name="Reptile">
  7.         <key column="animalId"/>
  8.         <property name="BodyTemperature"/>
  9.     </joined-subclass>
  10.     <joined-subclass name="Human">
  11.         <key column="animalId"/>
  12.         <property name="Name"/>
  13.         <property name="NickName"/>
  14.         <property name="Birthdate" type="Date"/>
  15.     </joined-subclass>
  16. </class>
  17. <class name="Family`1[[Reptile]]" table="ReptilesFamilies"
  18.        entity-name="ReptilesFamily">
  19.     <id name="Id" column="familyId">
  20.         <generator class="hilo"/>
  21.     </id>
  22.     <many-to-one name="Father" class="Reptile" cascade="all"/>
  23.     <many-to-one name="Mother" class="Reptile" cascade="all"/>
  24.     <set name="Childs" generic="true" cascade="all">
  25.         <key column="familyId" />
  26.         <one-to-many class="Reptile"/>
  27.     </set>
  28. </class>
  29. <class name="Family`1[[Human]]" table="HumanFamilies"
  30.        entity-name="HumanFamily">
  31.     <id name="Id" column="familyId">
  32.         <generator class="hilo"/>
  33.     </id>
  34.     <many-to-one name="Father" class="Human" cascade="all"/>
  35.     <many-to-one name="Mother" class="Human" cascade="all"/>
  36.     <set name="Childs" generic="true" cascade="all">
  37.         <key column="familyId" />
  38.         <one-to-many class="Human"/>
  39.     </set>
  40. </class>
复制代码
从映射可以看出,一个类实现所有类型家庭,但使用两个不同的强类型持久化映射。
3.Test

先保存一些Domain,注意这里用到了重载session.Save(实体名称, 实例)方法。
  1. using (var s = Sessions.OpenSession())
  2. using (var tx = s.BeginTransaction())
  3. {
  4.     var rf = new Reptile { Description = "父" };
  5.     var rm = new Reptile { Description = "母" };
  6.     var rc1 = new Reptile { Description = "子1" };
  7.     var rc2 = new Reptile { Description = "子2" };
  8.     var rfamily = new Family<Reptile>
  9.     {
  10.         Father = rf,
  11.         Mother = rm,
  12.         Childs = new HashedSet<Reptile> { rc1, rc2 }
  13.     };
  14.     var hf = new Human { Description = "父亲", Name = "Father" };
  15.     var hm = new Human { Description = "母亲", Name = "Mother" };
  16.     var hc1 = new Human { Description = "孩子", Name = "Child" };
  17.     var hfamily = new Family<Human>
  18.     {
  19.         Father = hf,
  20.         Mother = hm,
  21.         Childs = new HashedSet<Human> { hc1 }
  22.     };
  23.     //重载session.Save(实体名称, 实例)方法
  24.     s.Save("ReptilesFamily", rfamily);
  25.     s.Save("HumanFamily", hfamily);
  26.     tx.Commit();
  27. }
复制代码
运行结果:
1.png

查询:
  1. using (var s = Sessions.OpenSession())
  2. using (var tx = s.BeginTransaction())
  3. {
  4.     IList<Family<Human>> hf = s.CreateQuery("from HumanFamily").List<Family<Human>>();
  5.     Assert.That(hf.Count, Is.EqualTo(1));
  6.     Assert.That(hf[0].Father.Name, Is.EqualTo("Father"));
  7.     Assert.That(hf[0].Mother.Name, Is.EqualTo("Mother"));
  8.     Assert.That(hf[0].Childs.Count, Is.EqualTo(1));
  9.     IList<Family<Reptile>> rf = s.CreateQuery("from ReptilesFamily").List<Family<Reptile>>();
  10.     Assert.That(rf.Count, Is.EqualTo(1));
  11.     Assert.That(rf[0].Childs.Count, Is.EqualTo(2));
  12.     tx.Commit();
  13. }
复制代码
运行结果:
2.png

代码

Source Project Home:http://code.google.com/p/yjinglee/
SVN CheckOut:http://yjinglee.googlecode.com/svn/trunk/
结语

上面的映射还是有点复杂,可以想想更有趣的是只持久化Family类。因为我创建一张表(家族表)而我需要一些具体的类型Family和Family。在这种情况下我不能说Family是子类(在我的Domain中,没有Family的父类 )。可以使用、discriminator-value和where标签,大家可以先想想映射怎么改写呢。
参考资料

NHibernate文档:4.4. Dynamic models

来源:程序园用户自行投稿发布,如果侵权,请联系站长删除
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!
您需要登录后才可以回帖 登录 | 立即注册