首先谈一下背景。最近正要上马的项目中,遇到一个客户的需求:表名是动态的,根据数据库里的某些值来决定。举个例子来说

 

需求

有主表Student,有两列ID和Class

然后有从表XXXStudentDetail,其中XXX是Student表中的Class的值,取值范围不受限

也就是说每有一种Class就要添加一张StudentDetail表

 

面对需求,技术上考虑了两个方案,但是都碰壁了

1 在NamingStrategy上做文章,但是可重载的ClassToTableName方法传入的是Class名而不是object

2 在运行时动态生成mapping信息,但是NH的SessionFactory是有Configuration.BuildSessionFactory得到的,之后无法更改Configuration了(笔者也曾经尝试用反射强行生成mapping,插入到SessionFactory中的各个Dictionary中,但是一来工作量巨大,二来不了解NH的内部结构只得作罢)

msdn上的这段讨论, 觉得可以创建一个abstract的类用Attribute的方式来mapping StudentDetail表,其中TableName不指定,在运行时使用emit生成该类的子类,来map具体的某张表。但是问题在于可重载的GetTable方法的传入参数是Type而不是object,属于和NH的NamingStrategy路线卡在了一样的地方 


后来好在客户比较通融,接受了我们把XXX部分hard code的方案(客户也相应的把XXX的取值范围从200左右缩减到了5个,不然hard code也会死人的。。。)  

于是技术上的需求变成了一个实体类对应几个mapping,于是祭出我们今天的主角entity name

官网上给出了一个实例,是用一个泛型类对应几个mapping。 

下面就看看mapping

Child.hbm.xml


 

<?xml version="1.0" encoding="utf-8" ?>
<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2" namespace="SomeCompany.MySchool.Persistent.Model" assembly="SomeCompany.MySchool.Persistent.Model" default-lazy="true">
  
<joined-subclass name="ChildDetail" extends="Child" entity-name="Year2009Class1ChildDetail" table="Year2009Class1ChildDetail">
    
<key column="Id" not-null="true" />
    
<property name="Name" type="AnsiString" length="32"/>
    
<property name="EnrolmentDate" type="System.DateTime" not-null="true"/>
    
<property name="ClassName" type="AnsiString" length="32" not-null="true"/>
  
</joined-subclass>

  
<joined-subclass name="ChildDetail" extends="Child" entity-name="Year2009Class2ChildDetail" table="Year2009Class2ChildDetail">
    
<key column="Id" not-null="true" />
    
<property name="Name" type="AnsiString" length="32"/>
    
<property name="EnrolmentDate" type="System.DateTime" not-null="true"/>
    
<property name="ClassName" type="AnsiString" length="32" not-null="true"/>
  
</joined-subclass>
  
  
<joined-subclass name="ChildDetail" extends="Child" entity-name="Year2010Class1ChildDetail" table="Year2010Class1ChildDetail">
    
<key column="Id" not-null="true" />
    
<property name="Name" type="AnsiString" length="32"/>
    
<property name="EnrolmentDate" type="System.DateTime" not-null="true"/>
    
<property name="ClassName" type="AnsiString" length="32" not-null="true"/>
  
</joined-subclass>
</hibernate-mapping>

相关文章:

  • 2021-06-05
  • 2022-12-23
  • 2021-07-11
  • 2022-12-23
  • 2021-09-17
  • 2021-07-13
  • 2022-02-21
猜你喜欢
  • 2021-11-12
  • 2021-12-01
  • 2022-12-23
  • 2021-09-30
  • 2021-08-14
  • 2021-11-08
  • 2022-12-23
相关资源
相似解决方案