天天看點

如何使用Fluent Nhibernate中的Automapping進行OR Mapping映射

由于在項目中使用了NHibernate來作為ORMapping建構資料通路層,那麼就必須要配置Object和DataTable的映射。最早的項目中,我們使用了最傳統的XML配置檔案的方式編寫映射關系,但是這樣太麻煩,每次修改class和表時都要去修改對應的XML檔案,而且還容易出錯,一定有疏忽遺漏的地方,還不容易找出錯誤,是以在第二個項目中,我們使用了Fluent NHibernate的Mapping方式代替XML配置。使用Fluent NHibernate的最大好處是降低了出錯的機會,因為Fluent Nhibernate的配置是使用C#來編寫,可以智能感覺,而且還能編譯,不像原始的XML配置,寫錯了都不知道。

但是使用Fluent NHibernate的配置方式仍然是需要編寫Mapping代碼的,也就意味着,如果我更改class或者DataTable的時候,還要對應的更改該Mapping檔案。更多的修改意味着更多的風險,為了減少這方面的風險,同時為了減少配置的工作量,是以在最新的項目中采用了Fluent NHibernate中的Automapping。我們隻需要定義好映射的規則,就可以不對每個表和類分别編寫映射配置,而是按照規則進行自動的Mapping工作。這樣在修改class或者DataTable時,隻需要修改類和表即可,不需要再修改配置檔案。

要做到Automapping,就一定要定義好嚴格的命名規範,然後按照規範編寫Automapping規則,實作自動化的映射。比如我們可以定義如下的規則:

類名和字段名采用每個單詞首字母大寫的方式而資料庫表名和列名使用全部大寫,單詞之間下劃線分割的方式。(比如CostCenter類對應表COST_CENTER)

類中的主鍵使用Id命名,表中的主鍵使用表名+“_ID”的命名方式。(比如CostCenter中有public virtual long Id{get;set;},對應表中的列COST_CENTER_ID)

對于一對多的關系,使用父方的類名作為屬性名,表中使用父表的主鍵列名作為對應的外鍵列的列名。(比如一個班對應多個學生,在Class類中就有public virtual IList<Student> Students{get;set;},而在Student類中就必須使用Class作為屬性名:public virtual Class Class{get;set;})

對于SubClass,采用将多個子對象都存在同一個表中的方式實作,使用“TYPE”列作為DiscriminatorColumn,使用之類的類名作為子類的唯一辨別。

對于多對多的關系,把兩個類對應的表名進行排序,将小的排前面,然後将兩個表名連接配接起來,中間使用“_”分割。(比如Course和Student是多對多關系,那麼産生的中間表表名為COURSE_STUDENT)

對于枚舉,在資料庫中使用tinyint也就是一個Byte來存儲,枚舉在Automapping中作為UserType進行處理。

下面就來編寫Automapping的轉換規則,首先對String寫一個擴充方法,實作CostCenter到COST_CENTER的轉換:

對于1,需要實作IClassConvention實作如下:

同時對于列,需要使用IPropertyConvention接口,實作如下:

對于2,需要實作IIdConvention接口,另外我們采用的是Hilo值的主鍵生成方式,使用一個表HIBERNATE_UNIQUE_KEY存儲每個表的流水。具體實作如下:

對于3,一對多的情況,需要設定“一”的一方的Collection和“多”的一方的Reference,具體如下:

對于4SubClass的處理,需要涉及到指定要進行Discriminate的類,還有DiscriminateColumn,然後指定DiscriminateColumn中如何對Subclass進行Mapping。

這裡就需要重寫DefaultAutomappingConfiguration類,在該類中指定主鍵、Discriminate的類等,具體代碼如下:

然後就是關于DiscriminateColumn中的值如何映射成對應的Subclass,需要實作ISubclassConvention接口,代碼如下:

對于5多對多,就需要實作IHasManyToManyConvention接口,在這個接口中對兩個表名進行排序,然後進行連接配接表示中間表。具體代碼如下:

對于6枚舉的處理,需要指定枚舉為UserType,實作接口IUserTypeConvention,具體代碼如下:

實作了以上這幾個接口,那麼大部分情況下的Automapping都可以實作了。最後是将這些接口通知給FluentNhibernate,讓其應用這些接口,導入指定Assembly中的DomainModel,具體的實作方法是:

該方法傳回了一個AutoPersistenceModel,使用這個對象注冊到NHibernate中即可。

PS:以上代碼主要都是同僚在前期實作的,我隻是在後期接手了該工作,在此基礎上做了一些簡單的維護和修改。

本文轉自深藍居部落格園部落格,原文連結:http://www.cnblogs.com/studyzy/archive/2012/04/28/2475337.html,如需轉載請自行聯系原作者