1.数据类型对应
数据库中以二进制形式存储的类型,如binary,varbinanry,image等都可以映射成NHibernate中Byte数组,c#中也为byte数组,但是要注意大小写。
数据库中以字符串形式存储的类型,如varchar,nvarchar,char,ntext等可以映射成NHibernate中的String类型,c#中的string类型
数据库中的以数字形式存储的类型,如int,float,decimal等,对应到相应的数据类型即可。
数据库中系统表中的sysname类型对应到string
Nhibernate中还有BinaryBlob和StringClob两个类型,前者对应到数据库中的二进制,对应到c#中byte数组。后者对应到数据库中字符串类型,对应到c#中的string。两者都是用来处理数据长度较大的情况,使用并无特别之处。
在使用时发现部分数据类型之间的对应关系并不是严格限定的,如数据库中tinyint既可以映射成int类型,也可以映射成Byte,还有ntext可以对应到String和StringClob,灵活性比较大。详细的对应关系可以参考NHibernate文档中第四章O/R Mapping基础中的NHibernate 的类型一节。例子可以参考NHibernate\src\src\NHibernate.Test\TypesTest。注意点Nhibernate是区分大小的,如果有误是会报错的。
2.使用联合主键进行表间映射
这个知识点好像很难用文字描述清楚,附代码讲解会比较容易理解。
映射中用到的表:
table | person |
Key | Column |
★ | id |
★ | name |
table | account |
Key | Column |
★ | account_no |
★ | person_name |
★ | Person_id |
person与account的关系是一对多,通过person表中id,name和account中Person_id ,person_name进行关联。
person的映射配置文件为: <hibernate-mapping xmlns="urn:nhibernate-mapping-2.0"> <class name="NHibernateTest.Entity.Person,NHibernateTest.Entity" table="person"> <composite-id> <key-property name="Id" column="id" type="String"/> <key-property column="name" type="String" name="Name" /> </composite-id>//声明联合主键 <bag name="Accounts" inverse="true" lazy="true"> <key> <column name="person_id" /> <column name="person_name"/>//声明关联的栏位 </key > <one-to-many class="NHibernateTest.Entity.Account,NHibernateTest.Entity"/>//声明一对多关系 </bag> </class> </hibernate-mapping>
|
Account表映射配置文件: <hibernate-mapping xmlns="urn:nhibernate-mapping-2.0"> <class name="NHibernateTest.Entity.Account,NHibernateTest.Entity" table="account"> <composite-id> <key-property column="account_no" type="String" name="AccountNo"/> <key-many-to-one name="OnePerson" class="NHibernateTest.Entity.Person,NHibernateTest.Entity"> <column name="person_id"/> <column name="person_name"/>//声明关联的栏位 </key-many-to-one>//声明多对一关系 </composite-id> <property column="person_id" type="String" name="PersonId" update="false" insert="false"/> <property column="person_name" type="String" name="PersonName" update="false" insert="false"/> //通过设置update与insert为false,声明属性为只读 <property column="balance" type="Decimal" name="Balance" /> </class> </hibernate-mapping> |
注意点:在用到联合主键的实体类中,重写的Equals方法很重要,在Nhibernate在做数据筛选的时候,会用到Equals方法,如果Equals方法不准确的话,查询出来的数据是会有问题的。Equals方法设计原则是一定要保证数据的唯一性。Account类中的Equals方法
public override bool Equals( object obj ) { if( this == obj ) return true; if( ( obj == null ) || ( obj.GetType() != this.GetType() ) ) return false; Account castObj = (Account)obj; return (castObj!=null)&&(this.AccountNo.Equals(castObj.AccountNo) &&(this.OnePerson.Id.Equals(castObj.OnePerson.Id) &&this.OnePerson.Name.Equals(castObj.OnePerson.Name)));//请注意红色字体部分 } |
关于集合之间的对应问题,NHibernate中的bag和list可以对应到C#中的List,而因为C#中没有set这个集合,NHibernate用到第三方的set实现方法,如果需要要set对应必须引用Iesi.Collections.dll
相关知识点还可以参考nhibernet\src\src\NHibernate.DomainModel下的Inner,Middle和Outer,但是这些例子因为没有数据表对应,所以看起来会比较困难点。
3.使用同一个连接访问不同的数据库(针对sql server)
这个应该算是一个应用的小技巧了,只需要在映射文件的表名前加上库名就ok了,注意下面的代码的斜体部分。
<class name="NHibernateTest.Entity.Class,NHibernateTest.Entity" table="DatabaseName.dbo.tablename"> |
NHibernate在用到这个映射时会自动访问相应的database,同时再次访问项目中配置好的database也不会有问题。同一个连接可以在不同database之间切换。