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之間切換。
做人簡單一點好