Nhibernate+SQLite 入门实例指南二 类的继承、多态关系

 昨天忘记向源代码下载了,现在补上第一章的代码:http://files.cnblogs.com/9527/QuickStart1.rar

实例二、类的继承、多态关系

在我们实际设计过程中,经常碰到类的继承关系,比如一个电子产品商店,同时销售手机和MP3,所以在设计系统的时候我们把手机和MP3的共性如品牌、名称等抽象为一个类,而把它们的特性比如MP3有内存容量,手机有号码等,我们以不同的子类来体现。如下图:

Nhibernate+SQLite 入门实例指南二 类的继承、多态关系

在实际数据库的时候,最简单的就是每个子类拥有一个独立的表分别对应Mp3player和MobilePhone

Nhibernate+SQLite 入门实例指南二 类的继承、多态关系

由于MobilePhone和Mp3Player都是继承electronic,所以他们都Id,Name,Brand等属性,了我们分别为两个表编写映射文件:

MobilePhone.hbm.xml

Nhibernate+SQLite 入门实例指南二 类的继承、多态关系<?xml version="1.0" encoding="utf-8" ?> 
Nhibernate+SQLite 入门实例指南二 类的继承、多态关系
Nhibernate+SQLite 入门实例指南二 类的继承、多态关系
<hibernate-mapping xmlns="urn:nhibernate-mapping-2.0"> 
Nhibernate+SQLite 入门实例指南二 类的继承、多态关系
Nhibernate+SQLite 入门实例指南二 类的继承、多态关系
<class name="QuickStart2.Data.MobilePhone, QuickStart2.Data" table="t_mobilephone" > 
Nhibernate+SQLite 入门实例指南二 类的继承、多态关系
Nhibernate+SQLite 入门实例指南二 类的继承、多态关系
<id name="Id" column="id" type="Int32"> 
Nhibernate+SQLite 入门实例指南二 类的继承、多态关系
Nhibernate+SQLite 入门实例指南二 类的继承、多态关系
<generator class="identity" /> 
Nhibernate+SQLite 入门实例指南二 类的继承、多态关系
Nhibernate+SQLite 入门实例指南二 类的继承、多态关系
</id> 
Nhibernate+SQLite 入门实例指南二 类的继承、多态关系
Nhibernate+SQLite 入门实例指南二 类的继承、多态关系
<property name="Name" type="String(100)" column="name" /> 
Nhibernate+SQLite 入门实例指南二 类的继承、多态关系
Nhibernate+SQLite 入门实例指南二 类的继承、多态关系
<property name="Brand" type="String(20)" column="brand" /> 
Nhibernate+SQLite 入门实例指南二 类的继承、多态关系
Nhibernate+SQLite 入门实例指南二 类的继承、多态关系
<property name="Phonenumber" type="String(13)" column="phonenumber" /> 
Nhibernate+SQLite 入门实例指南二 类的继承、多态关系
Nhibernate+SQLite 入门实例指南二 类的继承、多态关系
</class> 
Nhibernate+SQLite 入门实例指南二 类的继承、多态关系
Nhibernate+SQLite 入门实例指南二 类的继承、多态关系
</hibernate-mapping> 
Nhibernate+SQLite 入门实例指南二 类的继承、多态关系
Nhibernate+SQLite 入门实例指南二 类的继承、多态关系Mp3Player.hbm.xml 
Nhibernate+SQLite 入门实例指南二 类的继承、多态关系
Nhibernate+SQLite 入门实例指南二 类的继承、多态关系
<?xml version="1.0" encoding="utf-8" ?> 
Nhibernate+SQLite 入门实例指南二 类的继承、多态关系
Nhibernate+SQLite 入门实例指南二 类的继承、多态关系
<hibernate-mapping xmlns="urn:nhibernate-mapping-2.0"> 
Nhibernate+SQLite 入门实例指南二 类的继承、多态关系
Nhibernate+SQLite 入门实例指南二 类的继承、多态关系
<class name="QuickStart2.Data.Mp3Player, QuickStart2.Data" table="t_mp3player" > 
Nhibernate+SQLite 入门实例指南二 类的继承、多态关系
Nhibernate+SQLite 入门实例指南二 类的继承、多态关系
<id name="Id" column="id" type="Int32"> 
Nhibernate+SQLite 入门实例指南二 类的继承、多态关系
Nhibernate+SQLite 入门实例指南二 类的继承、多态关系
<generator class="identity" /> 
Nhibernate+SQLite 入门实例指南二 类的继承、多态关系
Nhibernate+SQLite 入门实例指南二 类的继承、多态关系
</id> 
Nhibernate+SQLite 入门实例指南二 类的继承、多态关系
Nhibernate+SQLite 入门实例指南二 类的继承、多态关系
<property name="Name" type="String(100)" column="name" /> 
Nhibernate+SQLite 入门实例指南二 类的继承、多态关系
Nhibernate+SQLite 入门实例指南二 类的继承、多态关系
<property name="Brand" type="String(20)" column="brand" /> 
Nhibernate+SQLite 入门实例指南二 类的继承、多态关系
Nhibernate+SQLite 入门实例指南二 类的继承、多态关系
<property name="Mensize" type="Int32" column="mensize" /> 
Nhibernate+SQLite 入门实例指南二 类的继承、多态关系
Nhibernate+SQLite 入门实例指南二 类的继承、多态关系
</class> 
Nhibernate+SQLite 入门实例指南二 类的继承、多态关系
Nhibernate+SQLite 入门实例指南二 类的继承、多态关系
</hibernate-mapping> 
Nhibernate+SQLite 入门实例指南二 类的继承、多态关系
Nhibernate+SQLite 入门实例指南二 类的继承、多态关系


可以看到这两个映射和普通的映射文件没有什么不同。我们编写了一个段测试代码:

 

Nhibernate+SQLite 入门实例指南二 类的继承、多态关系ISession session=null
Nhibernate+SQLite 入门实例指南二 类的继承、多态关系
Nhibernate+SQLite 入门实例指南二 类的继承、多态关系ArrayList list
=null
Nhibernate+SQLite 入门实例指南二 类的继承、多态关系
Nhibernate+SQLite 入门实例指南二 类的继承、多态关系
try
Nhibernate+SQLite 入门实例指南二 类的继承、多态关系
Nhibernate+SQLite 入门实例指南二 类的继承、多态关系session
=SessionFactory.OpenSession(); 
Nhibernate+SQLite 入门实例指南二 类的继承、多态关系
Nhibernate+SQLite 入门实例指南二 类的继承、多态关系list
=(ArrayList)session.CreateCriteria(typeof(electronic)).List(); 
Nhibernate+SQLite 入门实例指南二 类的继承、多态关系
Nhibernate+SQLite 入门实例指南二 类的继承、多态关系}
 
Nhibernate+SQLite 入门实例指南二 类的继承、多态关系
Nhibernate+SQLite 入门实例指南二 类的继承、多态关系
catch(Exception e) 
Nhibernate+SQLite 入门实例指南二 类的继承、多态关系
Nhibernate+SQLite 入门实例指南二 类的继承、多态关系System.Console.WriteLine(e.Message); 
Nhibernate+SQLite 入门实例指南二 类的继承、多态关系
Nhibernate+SQLite 入门实例指南二 类的继承、多态关系System.Console.ReadLine(); 
Nhibernate+SQLite 入门实例指南二 类的继承、多态关系
Nhibernate+SQLite 入门实例指南二 类的继承、多态关系}
 
Nhibernate+SQLite 入门实例指南二 类的继承、多态关系
Nhibernate+SQLite 入门实例指南二 类的继承、多态关系
finally
Nhibernate+SQLite 入门实例指南二 类的继承、多态关系
Nhibernate+SQLite 入门实例指南二 类的继承、多态关系session.Close(); 
Nhibernate+SQLite 入门实例指南二 类的继承、多态关系
Nhibernate+SQLite 入门实例指南二 类的继承、多态关系}
 
Nhibernate+SQLite 入门实例指南二 类的继承、多态关系
Nhibernate+SQLite 入门实例指南二 类的继承、多态关系
foreach(electronic el in list) 
Nhibernate+SQLite 入门实例指南二 类的继承、多态关系
Nhibernate+SQLite 入门实例指南二 类的继承、多态关系System.Console.WriteLine(
"名称:º"+el.Name); 
Nhibernate+SQLite 入门实例指南二 类的继承、多态关系
Nhibernate+SQLite 入门实例指南二 类的继承、多态关系}
 
Nhibernate+SQLite 入门实例指南二 类的继承、多态关系
Nhibernate+SQLite 入门实例指南二 类的继承、多态关系

运行结果如下图所示:

Nhibernate+SQLite 入门实例指南二 类的继承、多态关系

我们看到NHibernate更据electronic自动找到它的两个子类Mp3Player和MobilePhone,生存两铁丝SQL语句分别查询两个表,下面输出的是,查询出来的结果。

为什么会这样子,在NHibernate中是用多态(polymorphism)来进行描述两个继承于同一父类的子类情况,在映射文件的Class节点中也有一个polymorphism的属性用来设定是隐式还是显式的使用查询多态,为什么我们的映射类中没有出现这个属性的设定呢,polymorphism = implicit是默认的。所以我们如果进行的是隐式的查询就可以不用进行设定。以下是摘自博客园renrenqq 翻译的NHibernate中文文档中对polymorphism的解释:

Implicit (隐式)的多态是指,如果查询中给出的是任何超类、该类实现的接口或者该类的名字,都会返回这个类的实例;如果查询中给出的是子类的名字,则会返回子类的实例。Explicit (显式)的多态是指,只有在查询中给出的明确是该类的名字时才会返回这个类的实例;同时只有当在这个 <class> 的定义中作为 <subclass> 或者 <joined-subclass> 出现的子类,才会可能返回。 大多数情况下,默认的polymorphism="implicit"都是合适的。 显式的多态在有两个不同的类映射到同一个表的时候很有用。(允许一个轻型的类,只包含部分表字段)。

通过这样的方式我们虽然也实现了我们想要的结果,但是对经验丰富的设计人员来说,这样的设计是并不合理的,一旦父类分生了变动,数据库里两个表都必须修改,而且从性能角度上来说也并不怎么理想。

所以,更据经验我们一般会吧两个表相同的字段合并成一个表,另建两个新表,只包含Mp3Player和MobilePhone的特有的属性。经过修改我们的数据库结构如下图如示:

Nhibernate+SQLite 入门实例指南二 类的继承、多态关系

可以看到主表于子表之间通过外键向连。

数据库修改以后,我们要重新设计映射文件,让它正确的映射到关系型数据库。

Electronic.hbm.xml

 

Nhibernate+SQLite 入门实例指南二 类的继承、多态关系<?xml version="1.0" encoding="utf-8" ?> 
Nhibernate+SQLite 入门实例指南二 类的继承、多态关系
Nhibernate+SQLite 入门实例指南二 类的继承、多态关系
<hibernate-mapping xmlns="urn:nhibernate-mapping-2.0"> 
Nhibernate+SQLite 入门实例指南二 类的继承、多态关系
Nhibernate+SQLite 入门实例指南二 类的继承、多态关系
<class name="QuickStart2.Data.electronic, QuickStart2.Data" table="t_electronic"> 
Nhibernate+SQLite 入门实例指南二 类的继承、多态关系
Nhibernate+SQLite 入门实例指南二 类的继承、多态关系
<id name="Id" column="id" type="Int32"> 
Nhibernate+SQLite 入门实例指南二 类的继承、多态关系
Nhibernate+SQLite 入门实例指南二 类的继承、多态关系
<generator class="identity" /> 
Nhibernate+SQLite 入门实例指南二 类的继承、多态关系
Nhibernate+SQLite 入门实例指南二 类的继承、多态关系
</id> 
Nhibernate+SQLite 入门实例指南二 类的继承、多态关系
Nhibernate+SQLite 入门实例指南二 类的继承、多态关系
<property name="Name" type="String(100)" column="name" /> 
Nhibernate+SQLite 入门实例指南二 类的继承、多态关系
Nhibernate+SQLite 入门实例指南二 类的继承、多态关系
<property name="Brand" type="String(20)" column="brand" /> 
Nhibernate+SQLite 入门实例指南二 类的继承、多态关系
Nhibernate+SQLite 入门实例指南二 类的继承、多态关系
<joined-subclass name="QuickStart2.Data.MobilePhone,QuickStart2.Data" table="t_mobile"> 
Nhibernate+SQLite 入门实例指南二 类的继承、多态关系
Nhibernate+SQLite 入门实例指南二 类的继承、多态关系
<key column="id" /> 
Nhibernate+SQLite 入门实例指南二 类的继承、多态关系
Nhibernate+SQLite 入门实例指南二 类的继承、多态关系
<property name="Phonenumber" type="String(13)" column="phonenumber" /> 
Nhibernate+SQLite 入门实例指南二 类的继承、多态关系
Nhibernate+SQLite 入门实例指南二 类的继承、多态关系
</joined-subclass> 
Nhibernate+SQLite 入门实例指南二 类的继承、多态关系
Nhibernate+SQLite 入门实例指南二 类的继承、多态关系
<joined-subclass name="QuickStart2.Data.Mp3Player,QuickStart2.Data" table="t_mp3"> 
Nhibernate+SQLite 入门实例指南二 类的继承、多态关系
Nhibernate+SQLite 入门实例指南二 类的继承、多态关系
<key column="id" /> 
Nhibernate+SQLite 入门实例指南二 类的继承、多态关系
Nhibernate+SQLite 入门实例指南二 类的继承、多态关系
<property name="Mensize" type="Int32" column="mensize" /> 
Nhibernate+SQLite 入门实例指南二 类的继承、多态关系
Nhibernate+SQLite 入门实例指南二 类的继承、多态关系
</joined-subclass> 
Nhibernate+SQLite 入门实例指南二 类的继承、多态关系
Nhibernate+SQLite 入门实例指南二 类的继承、多态关系
</class> 
Nhibernate+SQLite 入门实例指南二 类的继承、多态关系
Nhibernate+SQLite 入门实例指南二 类的继承、多态关系
</hibernate-mapping> 
Nhibernate+SQLite 入门实例指南二 类的继承、多态关系
Nhibernate+SQLite 入门实例指南二 类的继承、多态关系

通过映射文件我们可以看到,我们为主类建立了映射,两个子类在<joined-subclass>节点下进行了配置。

我们现编写一段数据插入代码来看看,NHibernate是怎么进行数据插入的

 

Nhibernate+SQLite 入门实例指南二 类的继承、多态关系public static void SaveMobilephone() 
Nhibernate+SQLite 入门实例指南二 类的继承、多态关系
Nhibernate+SQLite 入门实例指南二 类的继承、多态关系

Nhibernate+SQLite 入门实例指南二 类的继承、多态关系
Nhibernate+SQLite 入门实例指南二 类的继承、多态关系ISession session
=null
Nhibernate+SQLite 入门实例指南二 类的继承、多态关系
Nhibernate+SQLite 入门实例指南二 类的继承、多态关系ITransaction t
=null
Nhibernate+SQLite 入门实例指南二 类的继承、多态关系
Nhibernate+SQLite 入门实例指南二 类的继承、多态关系
try 
Nhibernate+SQLite 入门实例指南二 类的继承、多态关系
Nhibernate+SQLite 入门实例指南二 类的继承、多态关系

Nhibernate+SQLite 入门实例指南二 类的继承、多态关系
Nhibernate+SQLite 入门实例指南二 类的继承、多态关系session
=SessionFactory.OpenSession(); 
Nhibernate+SQLite 入门实例指南二 类的继承、多态关系
Nhibernate+SQLite 入门实例指南二 类的继承、多态关系t
=session.BeginTransaction(); 
Nhibernate+SQLite 入门实例指南二 类的继承、多态关系
Nhibernate+SQLite 入门实例指南二 类的继承、多态关系MobilePhone mp
=new MobilePhone(); 
Nhibernate+SQLite 入门实例指南二 类的继承、多态关系
Nhibernate+SQLite 入门实例指南二 类的继承、多态关系mp.Name
="575"
Nhibernate+SQLite 入门实例指南二 类的继承、多态关系
Nhibernate+SQLite 入门实例指南二 类的继承、多态关系mp.Brand
="Dopod"
Nhibernate+SQLite 入门实例指南二 类的继承、多态关系
Nhibernate+SQLite 入门实例指南二 类的继承、多态关系mp.Phonenumber
="13151921698"
Nhibernate+SQLite 入门实例指南二 类的继承、多态关系
Nhibernate+SQLite 入门实例指南二 类的继承、多态关系Mp3Player mp3
=new Mp3Player(); 
Nhibernate+SQLite 入门实例指南二 类的继承、多态关系
Nhibernate+SQLite 入门实例指南二 类的继承、多态关系mp3.Name
="SB200"
Nhibernate+SQLite 入门实例指南二 类的继承、多态关系
Nhibernate+SQLite 入门实例指南二 类的继承、多态关系mp3.Brand
="小霸王"
Nhibernate+SQLite 入门实例指南二 类的继承、多态关系
Nhibernate+SQLite 入门实例指南二 类的继承、多态关系mp3.Mensize
=513
Nhibernate+SQLite 入门实例指南二 类的继承、多态关系
Nhibernate+SQLite 入门实例指南二 类的继承、多态关系session.Save(mp3); 
Nhibernate+SQLite 入门实例指南二 类的继承、多态关系
Nhibernate+SQLite 入门实例指南二 类的继承、多态关系session.Save(mp); 
Nhibernate+SQLite 入门实例指南二 类的继承、多态关系
Nhibernate+SQLite 入门实例指南二 类的继承、多态关系session.Flush(); 
Nhibernate+SQLite 入门实例指南二 类的继承、多态关系
Nhibernate+SQLite 入门实例指南二 类的继承、多态关系t.Commit(); 
Nhibernate+SQLite 入门实例指南二 类的继承、多态关系
Nhibernate+SQLite 入门实例指南二 类的继承、多态关系}
 
Nhibernate+SQLite 入门实例指南二 类的继承、多态关系
Nhibernate+SQLite 入门实例指南二 类的继承、多态关系
catch(HibernateException e) 
Nhibernate+SQLite 入门实例指南二 类的继承、多态关系
Nhibernate+SQLite 入门实例指南二 类的继承、多态关系

Nhibernate+SQLite 入门实例指南二 类的继承、多态关系
Nhibernate+SQLite 入门实例指南二 类的继承、多态关系System.Console.Write(e.Message.ToString()); 
Nhibernate+SQLite 入门实例指南二 类的继承、多态关系
Nhibernate+SQLite 入门实例指南二 类的继承、多态关系
if(t!=null
Nhibernate+SQLite 入门实例指南二 类的继承、多态关系
Nhibernate+SQLite 入门实例指南二 类的继承、多态关系

Nhibernate+SQLite 入门实例指南二 类的继承、多态关系
Nhibernate+SQLite 入门实例指南二 类的继承、多态关系
try 
Nhibernate+SQLite 入门实例指南二 类的继承、多态关系
Nhibernate+SQLite 入门实例指南二 类的继承、多态关系

Nhibernate+SQLite 入门实例指南二 类的继承、多态关系
Nhibernate+SQLite 入门实例指南二 类的继承、多态关系t.Rollback(); 
Nhibernate+SQLite 入门实例指南二 类的继承、多态关系
Nhibernate+SQLite 入门实例指南二 类的继承、多态关系}
 
Nhibernate+SQLite 入门实例指南二 类的继承、多态关系
Nhibernate+SQLite 入门实例指南二 类的继承、多态关系
catch(HibernateException e1) 
Nhibernate+SQLite 入门实例指南二 类的继承、多态关系
Nhibernate+SQLite 入门实例指南二 类的继承、多态关系

Nhibernate+SQLite 入门实例指南二 类的继承、多态关系
Nhibernate+SQLite 入门实例指南二 类的继承、多态关系System.Console.Write(e1.Message.ToString()); 
Nhibernate+SQLite 入门实例指南二 类的继承、多态关系
Nhibernate+SQLite 入门实例指南二 类的继承、多态关系}
 
Nhibernate+SQLite 入门实例指南二 类的继承、多态关系
Nhibernate+SQLite 入门实例指南二 类的继承、多态关系}
 
Nhibernate+SQLite 入门实例指南二 类的继承、多态关系
Nhibernate+SQLite 入门实例指南二 类的继承、多态关系}
 
Nhibernate+SQLite 入门实例指南二 类的继承、多态关系
Nhibernate+SQLite 入门实例指南二 类的继承、多态关系
finally 
Nhibernate+SQLite 入门实例指南二 类的继承、多态关系
Nhibernate+SQLite 入门实例指南二 类的继承、多态关系

Nhibernate+SQLite 入门实例指南二 类的继承、多态关系
Nhibernate+SQLite 入门实例指南二 类的继承、多态关系session.Close(); 
Nhibernate+SQLite 入门实例指南二 类的继承、多态关系
Nhibernate+SQLite 入门实例指南二 类的继承、多态关系}
 
Nhibernate+SQLite 入门实例指南二 类的继承、多态关系
Nhibernate+SQLite 入门实例指南二 类的继承、多态关系System.Console.ReadLine(); 
Nhibernate+SQLite 入门实例指南二 类的继承、多态关系
Nhibernate+SQLite 入门实例指南二 类的继承、多态关系}
 
Nhibernate+SQLite 入门实例指南二 类的继承、多态关系
Nhibernate+SQLite 入门实例指南二 类的继承、多态关系

编译运行如上代码,在返回中我们看到如下结果

Nhibernate+SQLite 入门实例指南二 类的继承、多态关系

根据图片,我们可以看到,和前一次不同,NHibernate分四次,分别对主表和子表进行插入。

在运行我们在上一节中的查询代码,其结果是

Nhibernate+SQLite 入门实例指南二 类的继承、多态关系

我们可以看到,NHibernate用了一条组合查询,一次性就把三个表所有数据查询了出来。

从上面的例子我们可以看到,这样的设计,虽然从设计的逻辑上来说更加清晰明了,符合我们的设计习惯,但是多表操作带来的性能的消耗来是相当的可观,因此,如果我们的系统对性能上有相当的要求,我们就要考虑第三种方式。

我们把数据设计成不仅包含用父类的共同属性,也同是用不同的字段来表示两种产品的不同特性,这样如何来区别两个类呢,我们在数据库中加入一个”category”的字段来区别两种产品。

Nhibernate+SQLite 入门实例指南二 类的继承、多态关系

代码方面我们需要修改的也只有数据库的映射文件,把新映射文件修改成如下:

 

Nhibernate+SQLite 入门实例指南二 类的继承、多态关系<?xml version="1.0" encoding="utf-8" ?> 
Nhibernate+SQLite 入门实例指南二 类的继承、多态关系
Nhibernate+SQLite 入门实例指南二 类的继承、多态关系
<hibernate-mapping xmlns="urn:nhibernate-mapping-2.0"> 
Nhibernate+SQLite 入门实例指南二 类的继承、多态关系
Nhibernate+SQLite 入门实例指南二 类的继承、多态关系
<class name="QuickStart2.Data.electronic, QuickStart2.Data" table="t_elec"> 
Nhibernate+SQLite 入门实例指南二 类的继承、多态关系
Nhibernate+SQLite 入门实例指南二 类的继承、多态关系
<id name="Id" column="id" type="Int32"> 
Nhibernate+SQLite 入门实例指南二 类的继承、多态关系
Nhibernate+SQLite 入门实例指南二 类的继承、多态关系
<generator class="identity" /> 
Nhibernate+SQLite 入门实例指南二 类的继承、多态关系
Nhibernate+SQLite 入门实例指南二 类的继承、多态关系
</id> 
Nhibernate+SQLite 入门实例指南二 类的继承、多态关系
Nhibernate+SQLite 入门实例指南二 类的继承、多态关系
<discriminator column="category" type="String(10)" /> 
Nhibernate+SQLite 入门实例指南二 类的继承、多态关系
Nhibernate+SQLite 入门实例指南二 类的继承、多态关系
<property name="Name" type="String(100)" column="name" /> 
Nhibernate+SQLite 入门实例指南二 类的继承、多态关系
Nhibernate+SQLite 入门实例指南二 类的继承、多态关系
<property name="Brand" type="String(20)" column="brand" /> 
Nhibernate+SQLite 入门实例指南二 类的继承、多态关系
Nhibernate+SQLite 入门实例指南二 类的继承、多态关系
<subclass name="QuickStart2.Data.MobilePhone,QuickStart2.Data" discriminator-value="1" > 
Nhibernate+SQLite 入门实例指南二 类的继承、多态关系
Nhibernate+SQLite 入门实例指南二 类的继承、多态关系
<property name="Phonenumber" type="String(13)" column="phonenumber" /> 
Nhibernate+SQLite 入门实例指南二 类的继承、多态关系
Nhibernate+SQLite 入门实例指南二 类的继承、多态关系
</subclass> 
Nhibernate+SQLite 入门实例指南二 类的继承、多态关系
Nhibernate+SQLite 入门实例指南二 类的继承、多态关系
<subclass name="QuickStart2.Data.Mp3Player,QuickStart2.Data" discriminator-value="2" > 
Nhibernate+SQLite 入门实例指南二 类的继承、多态关系
Nhibernate+SQLite 入门实例指南二 类的继承、多态关系
<property name="Mensize" type="Int32" column="mensize" /> 
Nhibernate+SQLite 入门实例指南二 类的继承、多态关系
Nhibernate+SQLite 入门实例指南二 类的继承、多态关系
</subclass> 
Nhibernate+SQLite 入门实例指南二 类的继承、多态关系
Nhibernate+SQLite 入门实例指南二 类的继承、多态关系
</class> 
Nhibernate+SQLite 入门实例指南二 类的继承、多态关系
Nhibernate+SQLite 入门实例指南二 类的继承、多态关系
</hibernate-mapping> 
Nhibernate+SQLite 入门实例指南二 类的继承、多态关系
Nhibernate+SQLite 入门实例指南二 类的继承、多态关系

于前一节中的映射文件不一样的是,我们在映射文件中加入了一个识别器(discriminator),用来指定数据库中哪个字段是用来做为标识的。

在定义的子类的时候,也不能用joined-subclass 而要改成subclass joined-subclass不能支持discriminator-value属性,discriminator-value就是用来区分独立的子类当我们完成数据库的插入操作后(具体代码可以用上一节所提供的代码,由于代码完全相同,所以不再次提供了)我们可以看到,NHibernate只用了两次插入动作就完成了对数据的插入。

我们再运行查询的代码也可以用一条简单的SQL语句来完成操作,大家也可以试着用

list=(ArrayList)session.CreateQuery("from Mp3player").List();

list=(ArrayList)session.CreateQuery("from MobilePhone").List();

进行查询,在NHibernate生的结果如下图:

Nhibernate+SQLite 入门实例指南二 类的继承、多态关系

可以看到,NHibernate在读取数据的时候会自动更据标识读取Mp3Player或MobilePhone的内容。

但是这种方法也有它的硬伤,如果子类的特性太多,哪数据库的可读性就大打折扣了,甚至可以让人抓狂,对于系统的后期维护升级非常的不利。

因此、三种方法各有各的优点也各有缺点,我们要在设计的过程中更据实际情况进于权衡,然后才确定采用何种方式。
第二章代码下载:http://files.cnblogs.com/9527/QuickStart2.rar






    本文转自无心之柳.NET博客园博客,原文链接:http://www.cnblogs.com/9527/archive/2006/09/24/513505.html,如需转载请自行联系原作者



上一篇:InternetReadFile如何正确读取二进制文件


下一篇:MySQL基础知识——安装(五)