Posted on 2007-09-04 17:29
Glen 閱讀(3297)
評(píng)論(0) 編輯 收藏 所屬分類:
ORMapping
項(xiàng)目的框架已經(jīng)完成,今天把兩個(gè)不是很確定的知識(shí)點(diǎn)進(jìn)行學(xué)習(xí),并實(shí)現(xiàn)例程。但是其中還有一些知識(shí)點(diǎn)也只是在項(xiàng)目中實(shí)現(xiàn)了,并還沒(méi)有去深入的學(xué)習(xí)。只是把項(xiàng)目中應(yīng)用的一些經(jīng)驗(yàn)總結(jié),以便在我們以后的項(xiàng)目中更好的應(yīng)用NHibernate。
1.數(shù)據(jù)類型對(duì)應(yīng)
數(shù)據(jù)庫(kù)中以二進(jìn)制形式存儲(chǔ)的類型,如binary,varbinanry,image等都可以映射成NHibernate中Byte數(shù)組,c#中也為byte數(shù)組,但是要注意大小寫(xiě)。
數(shù)據(jù)庫(kù)中以字符串形式存儲(chǔ)的類型,如varchar,nvarchar,char,ntext等可以映射成NHibernate中的String類型,c#中的string類型
數(shù)據(jù)庫(kù)中的以數(shù)字形式存儲(chǔ)的類型,如int,float,decimal等,對(duì)應(yīng)到相應(yīng)的數(shù)據(jù)類型即可。
數(shù)據(jù)庫(kù)中系統(tǒng)表中的sysname類型對(duì)應(yīng)到string
Nhibernate中還有BinaryBlob和StringClob兩個(gè)類型,前者對(duì)應(yīng)到數(shù)據(jù)庫(kù)中的二進(jìn)制,對(duì)應(yīng)到c#中byte數(shù)組。后者對(duì)應(yīng)到數(shù)據(jù)庫(kù)中字符串類型,對(duì)應(yīng)到c#中的string。兩者都是用來(lái)處理數(shù)據(jù)長(zhǎng)度較大的情況,使用并無(wú)特別之處。
在使用時(shí)發(fā)現(xiàn)部分?jǐn)?shù)據(jù)類型之間的對(duì)應(yīng)關(guān)系并不是嚴(yán)格限定的,如數(shù)據(jù)庫(kù)中tinyint既可以映射成int類型,也可以映射成Byte,還有ntext可以對(duì)應(yīng)到String和StringClob,靈活性比較大。詳細(xì)的對(duì)應(yīng)關(guān)系可以參考NHibernate文檔中第四章O/R Mapping基礎(chǔ)中的NHibernate 的類型一節(jié)。例子可以參考NHibernate\src\src\NHibernate.Test\TypesTest。注意點(diǎn)Nhibernate是區(qū)分大小的,如果有誤是會(huì)報(bào)錯(cuò)的。
2.使用聯(lián)合主鍵進(jìn)行表間映射
這個(gè)知識(shí)點(diǎn)好像很難用文字描述清楚,附代碼講解會(huì)比較容易理解。
映射中用到的表:
table
|
person
|
Key
|
Column
|
★
|
id
|
★
|
name
|
table
|
account
|
Key
|
Column
|
★
|
account_no
|
★
|
person_name
|
★
|
Person_id
|
person與account的關(guān)系是一對(duì)多,通過(guò)person表中id,name和account中Person_id ,person_name進(jìn)行關(guān)聯(lián)。
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>//聲明聯(lián)合主鍵
<bag name="Accounts" inverse="true" lazy="true">
<key>
<column
name="person_id" />
<column
name="person_name"/>//聲明關(guān)聯(lián)的欄位
</key >
<one-to-many class="NHibernateTest.Entity.Account,NHibernateTest.Entity"/>//聲明一對(duì)多關(guān)系
</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"/>//聲明關(guān)聯(lián)的欄位
</key-many-to-one>//聲明多對(duì)一關(guān)系
</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"/> //通過(guò)設(shè)置update與insert為false,聲明屬性為只讀
<property column="balance" type="Decimal" name="Balance" />
</class>
</hibernate-mapping>
|
注意點(diǎn):在用到聯(lián)合主鍵的實(shí)體類中,重寫(xiě)的Equals方法很重要,在Nhibernate在做數(shù)據(jù)篩選的時(shí)候,會(huì)用到Equals方法,如果Equals方法不準(zhǔn)確的話,查詢出來(lái)的數(shù)據(jù)是會(huì)有問(wèn)題的。Equals方法設(shè)計(jì)原則是一定要保證數(shù)據(jù)的唯一性。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)));//請(qǐng)注意紅色字體部分
}
|
關(guān)于集合之間的對(duì)應(yīng)問(wèn)題,NHibernate中的bag和list可以對(duì)應(yīng)到C#中的List,而因?yàn)?span lang="EN-US">C#中沒(méi)有set這個(gè)集合,NHibernate用到第三方的set實(shí)現(xiàn)方法,如果需要要set對(duì)應(yīng)必須引用Iesi.Collections.dll
相關(guān)知識(shí)點(diǎn)還可以參考nhibernet\src\src\NHibernate.DomainModel下的Inner,Middle和Outer,但是這些例子因?yàn)闆](méi)有數(shù)據(jù)表對(duì)應(yīng),所以看起來(lái)會(huì)比較困難點(diǎn)。
3.使用同一個(gè)連接訪問(wèn)不同的數(shù)據(jù)庫(kù)(針對(duì)sql server)
這個(gè)應(yīng)該算是一個(gè)應(yīng)用的小技巧了,只需要在映射文件的表名前加上庫(kù)名就ok了,注意下面的代碼的斜體部分。
<class name="NHibernateTest.Entity.Class,NHibernateTest.Entity" table="DatabaseName.dbo.tablename">
|
NHibernate在用到這個(gè)映射時(shí)會(huì)自動(dòng)訪問(wèn)相應(yīng)的database,同時(shí)再次訪問(wèn)項(xiàng)目中配置好的database也不會(huì)有問(wèn)題。同一個(gè)連接可以在不同database之間切換。
做人簡(jiǎn)單一點(diǎn)好