NHibernate考察系列 01 基础环境

NHibernate考察系列 01 基础环境

    http://files.cnblogs.com/RicCC/nhibernate_1.2_example.rar

    目的
    考察NHibernate的一些主要特性,确定NHibernate的使用和基于NHibernate的设计方案。大致会包括以下一些方面:简单映射; many-to-many、many-to-one、one-to-many;枚举类型;自定义类型(简单类型和组合类型);条件式查询 (Criteria)、HQL、Native SQL、NamedQuery;继承,其中会包括对lasy、cascade等一些特性的考察。

    基础环境
    VS 2005、framework 2.0、SQL Server 2000、NHibernate-1.2.0.CR1。
    另外关于实体类和配置文件的自动生成,可以使用的一些工具有CodeSmith、ERStudio、Rational Rose等,本系列文章将采用手工编写的方式。
    实体的定义属于概念模型,数据库结构属于物理模型,映射文件是概念模型到物理模型之间的映射。网上一些文章讲述用CodeSmith根据数据库结构生成实 体类和映射文件,即完全的通过物理模型得到概念模型以及映射关系,这个做法是不完善的,可能是Data Driven设计方式。Java的Hibernate extension根据配置文件生成实体类和数据库脚本,因为基于配置文件的映射关系可以比较充分的了解概念模型和物理模型,所以这种做法比较恰当,是 Domain Driven设计倾向。使用CodeSmith从配置文件生成实体类和数据库脚本也是可以的。
    ERStudio的Logical Model可以看作轻量级的概念模型,它有到Physical Model的映射,因此可以考虑用它做Logical Model、Physical Model的设计,使用宏生成实体、配置文件和数据库。但因为它的长处只是在物理模型上,概念模型上的弱点可能会带来不小的限制。Rose在概念模型设计 上的优点是无疑的,也支持物理模型的设计,但不了解它对概念模型和物理模型之间映射的支持程度怎样,以及如何使用它的宏或者是COM做自定义生成,因此也 无法对这些方面进行评论。
    项目不大的情况下,手工完成这些工作也不会有多少工作量;使用简单的方式生成实体类和配置文件的基础部分,映射关系等复杂、特殊的地方手工更改,看来这是最适用的方法了。如果想完美的自动生成,估计得自己写Desiner,这样做没有太多必要。

    数据模型
    这一个系列使用的数据模型暂定如下图,有些结构方面用NHibernate是否可以实现、怎样实现是待考察项目。
    NHibernate考察系列 01 基础环境_第1张图片
    整个数据模型中的主键值,全部使用assigned的方式,即在程序中指定主键值,而不是使用NHibernate提供的自动主键生成方式。我希望尽量使 用业务上有意义的建作为主键,例如USER_ID值可能类似RicCC、COMPANY_ID值可能类似MS等。
    TBLPURCHASEORDER、TBLPURCHASEORDERLINE分别为采购订单的主档、明细(行项目),是one-to-many的关系。 主档中COMPANY_ID、VENDOR_ID分别关联到公司(TBLCOMPANY)、供应商(TBLVENDOR)表,表名这个采购订单是哪个公 司、向哪个供应商进行采购,另外包含创建日期、币别、总金额、付款条件、签核状态、签核人、签核日期和时间等;明细中的PLANT_ID、ITEM_ID 分别关联到工厂(TBLPLANT)、物料(TBLITEM)表,表名这个明细项目是哪个工厂、采购什么材料,另外包含采购单位、单价、数量、交货日期、 明细项目状态等。
    一个公司下面包含多个工厂,由TBLCOMPANY、TBLPLANT间的关系可以看出来。
    采购订单主档中的APPROVED_DATE、APPROVED_TIME故意将签核时间拆分成两个整数类型的字段保存,希望在对象模型中通过一个 DateTimeWrapperType自定义组件类型来实现。APPROVE_STATE、LINE_STATE分别表示签核状态、明细项目状态,在对 象模型中都使用枚举类型表示,数据库中一个字段是整型,保存枚举的整型值,另一个是字符串类型,保存枚举类型的字符串描述,用这种方式分别对枚举类型的支 持进行测试。
    有两个表:TBLPURCHASEORDERLINE、TBLPLANTITEM都是使用组合键作为主键(PO_NO+PO_LINE、PLANT_ID +ITEM_ID),NHibernate只支持单字段做主键,这两个地方用于考察是否可以使用自定义组合类型实现。
    在TBLPURCHASEORDER中的CURRENT_PO_LINE用于控制TBLPURCHASEORDERLINE表中PO_LINE的生成。创 建PurchaseOrder对象时,CURRENT_PO_LINE初始化为0。在创建第一个PurchaseOrderLine对象时,使用 CURRENT_PO_LINE的值加一个增量1(或者增量10),作为新创建PurchaseOrderLine对象的PO_LINE值,然后 CURRENT_PO_LINE也加上这个增量。即CURRENT_PO_LINE加一个增量,就是下一个PurchaseOrderLine对象的 PO_LINE值。这里主要是考察一下这种设计方式下,使用NHibernate的开发模式。
    TBLPLANTITEM表主要是考察继承方面。在对象模型上,PlantItem将继承自Item,这里有一些属性将使用父类的,例如 ITEM_DESCRIPTION;部分属性需要重写父类的,例如UNIT;另外子类会派生出自己的属性,例如ITEM_CATEGORY、 PURCHASE_CATEGORY等。
    TBLUSER用户表,TBLPURCHASEGROUP采购组。某个采购订单是由特定的采购组来负责的,这个采购组里面的用户可以对这个采购订单进行维护(修改、删除等)。采购组跟用户是many-to-many关系,主要用于测试many-to-many。

    数据库脚本
if   exists  ( select   *   from  dbo.sysobjects  where  id  =   object_id (N ' [dbo].[RefTBLCOMPANY9] ' and   OBJECTPROPERTY (id, N ' IsForeignKey ' =   1 )
ALTER   TABLE   [ dbo ] . [ TBLPLANT ]   DROP   CONSTRAINT  RefTBLCOMPANY9
GO

if   exists  ( select   *   from  dbo.sysobjects  where  id  =   object_id (N ' [dbo].[RefTBLCOMPANY2] ' and   OBJECTPROPERTY (id, N ' IsForeignKey ' =   1 )
ALTER   TABLE   [ dbo ] . [ TBLPURCHASEORDER ]   DROP   CONSTRAINT  RefTBLCOMPANY2
GO

if   exists  ( select   *   from  dbo.sysobjects  where  id  =   object_id (N ' [dbo].[RefTBLITEM11] ' and   OBJECTPROPERTY (id, N ' IsForeignKey ' =   1 )
ALTER   TABLE   [ dbo ] . [ TBLPLANTITEM ]   DROP   CONSTRAINT  RefTBLITEM11
GO

if   exists  ( select   *   from  dbo.sysobjects  where  id  =   object_id (N ' [dbo].[RefTBLITEM4] ' and   OBJECTPROPERTY (id, N ' IsForeignKey ' =   1 )
ALTER   TABLE   [ dbo ] . [ TBLPURCHASEORDERLINE ]   DROP   CONSTRAINT  RefTBLITEM4
GO

if   exists  ( select   *   from  dbo.sysobjects  where  id  =   object_id (N ' [dbo].[RefTBLPLANT10] ' and   OBJECTPROPERTY (id, N ' IsForeignKey ' =   1 )
ALTER   TABLE   [ dbo ] . [ TBLPLANTITEM ]   DROP   CONSTRAINT  RefTBLPLANT10
GO

if   exists  ( select   *   from  dbo.sysobjects  where  id  =   object_id (N ' [dbo].[RefTBLPLANT5] ' and   OBJECTPROPERTY (id, N ' IsForeignKey ' =   1 )
ALTER   TABLE   [ dbo ] . [ TBLPURCHASEORDERLINE ]   DROP   CONSTRAINT  RefTBLPLANT5
GO

if   exists  ( select   *   from  dbo.sysobjects  where  id  =   object_id (N ' [dbo].[RefTBLPURCHASEGROUP7] ' and   OBJECTPROPERTY (id, N ' IsForeignKey ' =   1 )
ALTER   TABLE   [ dbo ] . [ TBLPURCHASEGROUPUSER ]   DROP   CONSTRAINT  RefTBLPURCHASEGROUP7
GO

if   exists  ( select   *   from  dbo.sysobjects  where  id  =   object_id (N ' [dbo].[RefTBLPURCHASEGROUP8] ' and   OBJECTPROPERTY (id, N ' IsForeignKey ' =   1 )
ALTER   TABLE   [ dbo ] . [ TBLPURCHASEORDER ]   DROP   CONSTRAINT  RefTBLPURCHASEGROUP8
GO

if   exists  ( select   *   from  dbo.sysobjects  where  id  =   object_id (N ' [dbo].[RefTBLPURCHASEORDER1] ' and   OBJECTPROPERTY (id, N ' IsForeignKey ' =   1 )
ALTER   TABLE   [ dbo ] . [ TBLPURCHASEORDERLINE ]   DROP   CONSTRAINT  RefTBLPURCHASEORDER1
GO

if   exists  ( select   *   from  dbo.sysobjects  where  id  =   object_id (N ' [dbo].[RefTBLUSER6] ' and   OBJECTPROPERTY (id, N ' IsForeignKey ' =   1 )
ALTER   TABLE   [ dbo ] . [ TBLPURCHASEGROUPUSER ]   DROP   CONSTRAINT  RefTBLUSER6
GO

if   exists  ( select   *   from  dbo.sysobjects  where  id  =   object_id (N ' [dbo].[RefTBLVENDOR3] ' and   OBJECTPROPERTY (id, N ' IsForeignKey ' =   1 )
ALTER   TABLE   [ dbo ] . [ TBLPURCHASEORDER ]   DROP   CONSTRAINT  RefTBLVENDOR3
GO

if   exists  ( select   *   from  dbo.sysobjects  where  id  =   object_id (N ' [dbo].[TBLCOMPANY] ' and   OBJECTPROPERTY (id, N ' IsUserTable ' =   1 )
drop   table   [ dbo ] . [ TBLCOMPANY ]
GO

if   exists  ( select   *   from  dbo.sysobjects  where  id  =   object_id (N ' [dbo].[TBLITEM] ' and   OBJECTPROPERTY (id, N ' IsUserTable ' =   1 )
drop   table   [ dbo ] . [ TBLITEM ]
GO

if   exists  ( select   *   from  dbo.sysobjects  where  id  =   object_id (N ' [dbo].[TBLPLANT] ' and   OBJECTPROPERTY (id, N ' IsUserTable ' =   1 )
drop   table   [ dbo ] . [ TBLPLANT ]
GO

if   exists  ( select   *   from  dbo.sysobjects  where  id  =   object_id (N ' [dbo].[TBLPLANTITEM] ' and   OBJECTPROPERTY (id, N ' IsUserTable ' =   1 )
drop   table   [ dbo ] . [ TBLPLANTITEM ]
GO

if   exists  ( select   *   from  dbo.sysobjects  where  id  =   object_id (N ' [dbo].[TBLPURCHASEGROUP] ' and   OBJECTPROPERTY (id, N ' IsUserTable ' =   1 )
drop   table   [ dbo ] . [ TBLPURCHASEGROUP ]
GO

if   exists  ( select   *   from  dbo.sysobjects  where  id  =   object_id (N ' [dbo].[TBLPURCHASEGROUPUSER] ' and   OBJECTPROPERTY (id, N ' IsUserTable ' =   1 )
drop   table   [ dbo ] . [ TBLPURCHASEGROUPUSER ]
GO

if   exists  ( select   *   from  dbo.sysobjects  where  id  =   object_id (N ' [dbo].[TBLPURCHASEORDER] ' and   OBJECTPROPERTY (id, N ' IsUserTable ' =   1 )
drop   table   [ dbo ] . [ TBLPURCHASEORDER ]
GO

if   exists  ( select   *   from  dbo.sysobjects  where  id  =   object_id (N ' [dbo].[TBLPURCHASEORDERLINE] ' and   OBJECTPROPERTY (id, N ' IsUserTable ' =   1 )
drop   table   [ dbo ] . [ TBLPURCHASEORDERLINE ]
GO

if   exists  ( select   *   from  dbo.sysobjects  where  id  =   object_id (N ' [dbo].[TBLUSER] ' and   OBJECTPROPERTY (id, N ' IsUserTable ' =   1 )
drop   table   [ dbo ] . [ TBLUSER ]
GO

if   exists  ( select   *   from  dbo.sysobjects  where  id  =   object_id (N ' [dbo].[TBLVENDOR] ' and   OBJECTPROPERTY (id, N ' IsUserTable ' =   1 )
drop   table   [ dbo ] . [ TBLVENDOR ]
GO

CREATE   TABLE   [ dbo ] . [ TBLCOMPANY ]  (
    
[ COMPANY_ID ]   [ nvarchar ]  ( 4 NOT   NULL  ,
    
[ COMPANY_NAME ]   [ nvarchar ]  ( 70 NULL  
ON   [ PRIMARY ]
GO

CREATE   TABLE   [ dbo ] . [ TBLITEM ]  (
    
[ ITEM_ID ]   [ nvarchar ]  ( 18 NOT   NULL  ,
    
[ ITEM_DESCRIPTION ]   [ nvarchar ]  ( 50 NULL  ,
    
[ UNIT ]   [ nvarchar ]  ( 10 NULL  ,
    
[ PRICE ]   [ decimal ] ( 18 6 NULL  
ON   [ PRIMARY ]
GO

CREATE   TABLE   [ dbo ] . [ TBLPLANT ]  (
    
[ PLANT_ID ]   [ nvarchar ]  ( 4 NOT   NULL  ,
    
[ COMPANY_ID ]   [ nvarchar ]  ( 4 NOT   NULL  ,
    
[ PLANT_DESCRIPTION ]   [ nvarchar ]  ( 70 NULL  
ON   [ PRIMARY ]
GO

CREATE   TABLE   [ dbo ] . [ TBLPLANTITEM ]  (
    
[ PLANT_ID ]   [ nvarchar ]  ( 4 NOT   NULL  ,
    
[ ITEM_ID ]   [ nvarchar ]  ( 18 NOT   NULL  ,
    
[ UNIT ]   [ nvarchar ]  ( 10 NULL  ,
    
[ ITEM_CATEGORY ]   [ nvarchar ]  ( 3 NULL  ,
    
[ PURCHASE_CATEGORY ]   [ nvarchar ]  ( 5 NULL  ,
    
[ STOCK_OPTION ]   [ int ]   NULL  
ON   [ PRIMARY ]
GO

CREATE   TABLE   [ dbo ] . [ TBLPURCHASEGROUP ]  (
    
[ PURCHASE_GROUP_ID ]   [ nvarchar ]  ( 3 NOT   NULL  ,
    
[ DESCRIPTION ]   [ nvarchar ]  ( 50 NULL  
ON   [ PRIMARY ]
GO

CREATE   TABLE   [ dbo ] . [ TBLPURCHASEGROUPUSER ]  (
    
[ USER_ID ]   [ nvarchar ]  ( 18 NOT   NULL  ,
    
[ PURCHASE_GROUP_ID ]   [ nvarchar ]  ( 3 NOT   NULL  
ON   [ PRIMARY ]
GO

CREATE   TABLE   [ dbo ] . [ TBLPURCHASEORDER ]  (
    
[ PO_NO ]   [ nvarchar ]  ( 18 NOT   NULL  ,
    
[ COMPANY_ID ]   [ nvarchar ]  ( 4 NOT   NULL  ,
    
[ VENDOR_ID ]   [ nvarchar ]  ( 12 NOT   NULL  ,
    
[ PURCHASE_GROUP_ID ]   [ nvarchar ]  ( 3 NOT   NULL  ,
    
[ CREATE_DATE ]   [ datetime ]   NOT   NULL  ,
    
[ CURRENCY ]   [ nvarchar ]  ( 5 NOT   NULL  ,
    
[ TOTAL_AMOUNT ]   [ decimal ] ( 18 0 NULL  ,
    
[ PAYMENT_TERMS ]   [ nvarchar ]  ( 30 NULL  ,
    
[ APPROVE_STATE ]   [ nvarchar ]  ( 3 NULL  ,
    
[ APPROVED_BY ]   [ nvarchar ]  ( 16 NULL  ,
    
[ APPROVED_DATE ]   [ int ]   NULL  ,
    
[ APPROVED_TIME ]   [ int ]   NULL  ,
    
[ CURRENT_PO_LINE ]   [ nvarchar ]  ( 5 NULL  
ON   [ PRIMARY ]
GO

CREATE   TABLE   [ dbo ] . [ TBLPURCHASEORDERLINE ]  (
    
[ PO_NO ]   [ nvarchar ]  ( 18 NOT   NULL  ,
    
[ PO_LINE ]   [ nvarchar ]  ( 5 NOT   NULL  ,
    
[ PLANT_ID ]   [ nvarchar ]  ( 4 NOT   NULL  ,
    
[ ITEM_ID ]   [ nvarchar ]  ( 18 NOT   NULL  ,
    
[ UNIT ]   [ nvarchar ]  ( 10 NULL  ,
    
[ PRICE ]   [ decimal ] ( 18 6 NULL  ,
    
[ QUANTITY ]   [ decimal ] ( 18 6 NULL  ,
    
[ REQUEST_DATE ]   [ int ]   NULL  ,
    
[ LINE_STATE ]   [ int ]   NULL  
ON   [ PRIMARY ]
GO

CREATE   TABLE   [ dbo ] . [ TBLUSER ]  (
    
[ USER_ID ]   [ nvarchar ]  ( 18 NOT   NULL  ,
    
[ USER_NAME ]   [ nvarchar ]  ( 40 NULL  
ON   [ PRIMARY ]
GO

CREATE   TABLE   [ dbo ] . [ TBLVENDOR ]  (
    
[ VENDOR_ID ]   [ nvarchar ]  ( 12 NOT   NULL  ,
    
[ VENDOR_NAME ]   [ nvarchar ]  ( 50 NULL  
ON   [ PRIMARY ]
GO

ALTER   TABLE   [ dbo ] . [ TBLCOMPANY ]   WITH   NOCHECK   ADD  
    
CONSTRAINT   [ PK_TBLCOMPANY ]   PRIMARY   KEY    CLUSTERED  
    (
        
[ COMPANY_ID ]
    )  
ON   [ PRIMARY ]  
GO

ALTER   TABLE   [ dbo ] . [ TBLITEM ]   WITH   NOCHECK   ADD  
    
CONSTRAINT   [ PK_TBLITEM ]   PRIMARY   KEY    CLUSTERED  
    (
        
[ ITEM_ID ]
    )  
ON   [ PRIMARY ]  
GO

ALTER   TABLE   [ dbo ] . [ TBLPLANT ]   WITH   NOCHECK   ADD  
    
CONSTRAINT   [ PK_TBLPLANT ]   PRIMARY   KEY    CLUSTERED  
    (
        
[ PLANT_ID ]
    )  
ON   [ PRIMARY ]  
GO

ALTER   TABLE   [ dbo ] . [ TBLPURCHASEGROUP ]   WITH   NOCHECK   ADD  
    
CONSTRAINT   [ PK_TBLPURCHASEGROUP ]   PRIMARY   KEY    CLUSTERED  
    (
        
[ PURCHASE_GROUP_ID ]
    )  
ON   [ PRIMARY ]  
GO

ALTER   TABLE   [ dbo ] . [ TBLPURCHASEORDER ]   WITH   NOCHECK   ADD  
    
CONSTRAINT   [ PK_TBLPURCHASEORDER ]   PRIMARY   KEY    CLUSTERED  
    (
        
[ PO_NO ]
    )  
ON   [ PRIMARY ]  
GO

ALTER   TABLE   [ dbo ] . [ TBLPURCHASEORDERLINE ]   WITH   NOCHECK   ADD  
    
CONSTRAINT   [ PK_TBLPURCHASEORDERLINE ]   PRIMARY   KEY    CLUSTERED  
    (
        
[ PO_NO ] ,
        
[ PO_LINE ]
    )  
ON   [ PRIMARY ]  
GO

ALTER   TABLE   [ dbo ] . [ TBLUSER ]   WITH   NOCHECK   ADD  
    
CONSTRAINT   [ PK_TBLUSER ]   PRIMARY   KEY    CLUSTERED  
    (
        
[ USER_ID ]
    )  
ON   [ PRIMARY ]  
GO

ALTER   TABLE   [ dbo ] . [ TBLVENDOR ]   WITH   NOCHECK   ADD  
    
CONSTRAINT   [ PK_TBLVENDOR ]   PRIMARY   KEY    CLUSTERED  
    (
        
[ VENDOR_ID ]
    )  
ON   [ PRIMARY ]  
GO

ALTER   TABLE   [ dbo ] . [ TBLPLANTITEM ]   ADD  
    
CONSTRAINT   [ Entity1PK ]   PRIMARY   KEY    NONCLUSTERED  
    (
        
[ PLANT_ID ] ,
        
[ ITEM_ID ]
    )  
ON   [ PRIMARY ]  
GO

ALTER   TABLE   [ dbo ] . [ TBLPURCHASEGROUPUSER ]   ADD  
    
CONSTRAINT   [ PKTBLPURCHASEGROUPUSER ]   PRIMARY   KEY    NONCLUSTERED  
    (
        
[ USER_ID ] ,
        
[ PURCHASE_GROUP_ID ]
    )  
ON   [ PRIMARY ]  
GO

ALTER   TABLE   [ dbo ] . [ TBLPLANT ]   ADD  
    
CONSTRAINT   [ RefTBLCOMPANY9 ]   FOREIGN   KEY  
    (
        
[ COMPANY_ID ]
    ) 
REFERENCES   [ dbo ] . [ TBLCOMPANY ]  (
        
[ COMPANY_ID ]
    )
GO

ALTER   TABLE   [ dbo ] . [ TBLPLANTITEM ]   ADD  
    
CONSTRAINT   [ RefTBLITEM11 ]   FOREIGN   KEY  
    (
        
[ ITEM_ID ]
    ) 
REFERENCES   [ dbo ] . [ TBLITEM ]  (
        
[ ITEM_ID ]
    ),
    
CONSTRAINT   [ RefTBLPLANT10 ]   FOREIGN   KEY  
    (
        
[ PLANT_ID ]
    ) 
REFERENCES   [ dbo ] . [ TBLPLANT ]  (
        
[ PLANT_ID ]
    )
GO

ALTER   TABLE   [ dbo ] . [ TBLPURCHASEGROUPUSER ]   ADD  
    
CONSTRAINT   [ RefTBLPURCHASEGROUP7 ]   FOREIGN   KEY  
    (
        
[ PURCHASE_GROUP_ID ]
    ) 
REFERENCES   [ dbo ] . [ TBLPURCHASEGROUP ]  (
        
[ PURCHASE_GROUP_ID ]
    ),
    
CONSTRAINT   [ RefTBLUSER6 ]   FOREIGN   KEY  
    (
        
[ USER_ID ]
    ) 
REFERENCES   [ dbo ] . [ TBLUSER ]  (
        
[ USER_ID ]
    )
GO

ALTER   TABLE   [ dbo ] . [ TBLPURCHASEORDER ]   ADD  
    
CONSTRAINT   [ RefTBLCOMPANY2 ]   FOREIGN   KEY  
    (
        
[ COMPANY_ID ]
    ) 
REFERENCES   [ dbo ] . [ TBLCOMPANY ]  (
        
[ COMPANY_ID ]
    ),
    
CONSTRAINT   [ RefTBLPURCHASEGROUP8 ]   FOREIGN   KEY  
    (
        
[ PURCHASE_GROUP_ID ]
    ) 
REFERENCES   [ dbo ] . [ TBLPURCHASEGROUP ]  (
        
[ PURCHASE_GROUP_ID ]
    ),
    
CONSTRAINT   [ RefTBLVENDOR3 ]   FOREIGN   KEY  
    (
        
[ VENDOR_ID ]
    ) 
REFERENCES   [ dbo ] . [ TBLVENDOR ]  (
        
[ VENDOR_ID ]
    )
GO

ALTER   TABLE   [ dbo ] . [ TBLPURCHASEORDERLINE ]   ADD  
    
CONSTRAINT   [ RefTBLITEM4 ]   FOREIGN   KEY  
    (
        
[ ITEM_ID ]
    ) 
REFERENCES   [ dbo ] . [ TBLITEM ]  (
        
[ ITEM_ID ]
    ),
    
CONSTRAINT   [ RefTBLPLANT5 ]   FOREIGN   KEY  
    (
        
[ PLANT_ID ]
    ) 
REFERENCES   [ dbo ] . [ TBLPLANT ]  (
        
[ PLANT_ID ]
    ),
    
CONSTRAINT   [ RefTBLPURCHASEORDER1 ]   FOREIGN   KEY  
    (
        
[ PO_NO ]
    ) 
REFERENCES   [ dbo ] . [ TBLPURCHASEORDER ]  (
        
[ PO_NO ]
    )
GO

你可能感兴趣的:(NHibernate考察系列 01 基础环境)