赏勿 发表于 2025-5-29 15:01:30

NHibernate2.1新特性之entity-name

本节内容
       
[*]概览       
[*]典型实例
               
[*]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

public abstract class Animal
{
    public virtual int Id { get; private set; }
    public virtual string Description { get; set; }
}

public class Reptile : Animal
{
    public virtual float BodyTemperature { get; set; }
}

public class Human : Animal
{
    public virtual string Name { get; set; }
    public virtual string NickName { get; set; }
    public virtual DateTime Birthdate { get; set; }
}

public class Family<T> where T : Animal
{
    public virtual int Id { get; private set; }
    public virtual T Father { get; set; }
    public virtual T Mother { get; set; }
    public virtual ISet<T> Childs { get; set; }
}2.Mapping

在数据库中我想每个Animal使用不同的表,所以需要三个不同的表。当然,所有"Kinds"的家庭只有一个表可能不够,因为我不可能有一个ForeignKey指向两个表。我需要一个表有强类型Family。使用NHibernate新的标签:实体名称(entity-name)可以做到。
<class name="Animal">
    <id name="Id" column="animalId">
      <generator class="hilo"/>
    </id>
    <property name="Description"/>

    <joined-subclass name="Reptile">
      <key column="animalId"/>
      <property name="BodyTemperature"/>
    </joined-subclass>

    <joined-subclass name="Human">
      <key column="animalId"/>
      <property name="Name"/>
      <property name="NickName"/>
      <property name="Birthdate" type="Date"/>
    </joined-subclass>
</class>

<class name="Family`1[]" table="ReptilesFamilies"
       entity-name="ReptilesFamily">
    <id name="Id" column="familyId">
      <generator class="hilo"/>
    </id>
    <many-to-one name="Father" class="Reptile" cascade="all"/>
    <many-to-one name="Mother" class="Reptile" cascade="all"/>
    <set name="Childs" generic="true" cascade="all">
      <key column="familyId" />
      <one-to-many class="Reptile"/>
    </set>
</class>

<class name="Family`1[]" table="HumanFamilies"
       entity-name="HumanFamily">
    <id name="Id" column="familyId">
      <generator class="hilo"/>
    </id>
    <many-to-one name="Father" class="Human" cascade="all"/>
    <many-to-one name="Mother" class="Human" cascade="all"/>
    <set name="Childs" generic="true" cascade="all">
      <key column="familyId" />
      <one-to-many class="Human"/>
    </set>
</class>从映射可以看出,一个类实现所有类型家庭,但使用两个不同的强类型持久化映射。
3.Test

先保存一些Domain,注意这里用到了重载session.Save(实体名称, 实例)方法。
using (var s = Sessions.OpenSession())
using (var tx = s.BeginTransaction())
{
    var rf = new Reptile { Description = "父" };
    var rm = new Reptile { Description = "母" };
    var rc1 = new Reptile { Description = "子1" };
    var rc2 = new Reptile { Description = "子2" };
    var rfamily = new Family<Reptile>
    {
      Father = rf,
      Mother = rm,
      Childs = new HashedSet<Reptile> { rc1, rc2 }
    };
    var hf = new Human { Description = "父亲", Name = "Father" };
    var hm = new Human { Description = "母亲", Name = "Mother" };
    var hc1 = new Human { Description = "孩子", Name = "Child" };
    var hfamily = new Family<Human>
    {
      Father = hf,
      Mother = hm,
      Childs = new HashedSet<Human> { hc1 }
    };
    //重载session.Save(实体名称, 实例)方法
    s.Save("ReptilesFamily", rfamily);
    s.Save("HumanFamily", hfamily);
    tx.Commit();
}运行结果:

查询:
using (var s = Sessions.OpenSession())
using (var tx = s.BeginTransaction())
{
    IList<Family<Human>> hf = s.CreateQuery("from HumanFamily").List<Family<Human>>();
    Assert.That(hf.Count, Is.EqualTo(1));
    Assert.That(hf.Father.Name, Is.EqualTo("Father"));
    Assert.That(hf.Mother.Name, Is.EqualTo("Mother"));
    Assert.That(hf.Childs.Count, Is.EqualTo(1));

    IList<Family<Reptile>> rf = s.CreateQuery("from ReptilesFamily").List<Family<Reptile>>();
    Assert.That(rf.Count, Is.EqualTo(1));
    Assert.That(rf.Childs.Count, Is.EqualTo(2));

    tx.Commit();
}运行结果:

代码

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

来源:程序园用户自行投稿发布,如果侵权,请联系站长删除
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!

时思美 发表于 2025-10-27 03:41:56

yyds。多谢分享

乳杂丫 发表于 2025-11-2 10:49:38

谢谢楼主提供!

叭遭段 发表于 2025-11-15 04:48:25

分享、互助 让互联网精神温暖你我

挽幽 发表于 2025-12-15 08:27:28

谢谢分享,试用一下

杠氯 发表于 2025-12-26 15:18:04

谢谢分享,试用一下

叟澡帅 发表于 2025-12-28 09:50:00

感谢分享,学习下。

仁夹篇 发表于 2025-12-29 02:14:20

喜欢鼓捣这些软件,现在用得少,谢谢分享!

辉伫 发表于 2026-1-3 23:15:44

感谢分享,下载保存了,貌似很强大

蔬陶 发表于 2026-1-15 21:49:09

感谢分享,学习下。

欧阳梓蓓 发表于 2026-1-19 10:12:22

鼓励转贴优秀软件安全工具和文档!

杆树 发表于 2026-1-24 12:36:25

谢谢楼主提供!

山芷兰 发表于 2026-1-28 04:02:05

很好很强大我过来先占个楼 待编辑

魁睥 发表于 2026-1-29 07:52:55

很好很强大我过来先占个楼 待编辑

肿圬后 发表于 2026-1-30 07:30:30

鼓励转贴优秀软件安全工具和文档!

阎怀慕 发表于 2026-1-31 21:34:34

用心讨论,共获提升!

挫莉虻 发表于 2026-2-3 07:10:25

喜欢鼓捣这些软件,现在用得少,谢谢分享!

晦险忿 发表于 2026-2-4 04:36:06

谢谢分享,试用一下

尹心菱 发表于 2026-2-4 06:41:02

感谢,下载保存了

咪四 发表于 2026-2-5 08:32:24

懂技术并乐意极积无私分享的人越来越少。珍惜
页: [1] 2
查看完整版本: NHibernate2.1新特性之entity-name