天天看點

[NHibernate]使用AttributeNHibernate.Mapping.Attributes

<a href="http://www.cnblogs.com/wolf-sun/p/3694592.html">[nhibernate]體系結構</a>

<a href="http://www.cnblogs.com/wolf-sun/p/3694901.html">[nhibernate]isessionfactory配置</a>

<a href="http://www.cnblogs.com/wolf-sun/p/3704012.html">[nhibernate]持久化類(persistent classes)</a>

<a href="http://www.cnblogs.com/wolf-sun/p/3705229.html">[nhibernate]o/r mapping基礎</a>

<a href="http://www.cnblogs.com/wolf-sun/p/3720259.html">[nhibernate]關聯映射</a>

<a href="http://www.cnblogs.com/wolf-sun/p/3721528.html">[nhibernate]parent/child</a>

<a href="http://www.cnblogs.com/wolf-sun/p/3724052.html">[nhibernate]緩存(nhibernate.caches)</a>

nhibernate.mapping.attributes是nhibernate的附加軟體,它是pierre henri kuat(aka kpixel)貢獻的;以前的實作者是john morris.nhibernate需要映射資訊來綁定你的域對象到資料庫。通常他們被寫在(并且被儲存在)分散的hbm.xml檔案裡。

使用nhibernate.mapping.attributes,你可以使用.net屬性(attributes)來修飾你的實體和被用于産生.hbm.xml映射(檔案或者流)的屬性(attributes).是以,你将不再會為這些令人厭惡的檔案而煩惱。

這個庫裡面的内容包括:

nhibernate.mapping.attributes:你需要的唯一工程(作為最終使用者)。

test一個使用屬性(attributes)和hbmserializer的簡單用例,是nunit的testfixture。

genaerator:用來産生屬性(attributes)和hbmwriter的程式。

refly:感謝jonathan de halleux提供這個庫,它使的産生代碼變得如此簡單。

重要提示

這個庫是使用檔案/src/nhibernate.mapping.attributes/nhibernate-mapping-2.0.xsd(它嵌入在程式集中能檢查産生的xml流的合法性)産生的,這個檔案可能在nhibernate每次釋出新版本時發生變化,是以你應該在不同的版本中使用它時,重新生成它(打開generator工程,編譯并且運作generator項目)。但是,在0.8之前的版本中它并沒有通過測試。

最終使用者類 是nhibernate.mapping.attributes.hbmserializer.這個類序列化你的域模型到映射流.你可以逐個序列化程式集中的類.nhibernate.mapping.attributes.test可以作為參考. 

第一步用屬性(attributes)修飾你的實體;你可以用 [class], [subclass], [joinedsubclass]或者[component].然後,修飾成員(字段/屬性properties);它們能夠代替很多映射中需要使用的屬性(attributes ),例如:

完成這個步驟後,使用nhibernate.mapping.attributes.hbmserializer:(這裡我們使用了default ,它是一個執行個體,在你不必須/不想自己建立它時使用).

[NHibernate]使用AttributeNHibernate.Mapping.Attributes
[NHibernate]使用AttributeNHibernate.Mapping.Attributes

注意:正如你所見:nhibernate.mapping.attributes是沒有(真正的)侵入性的.在你的對象上設定屬性(attributes ),不會強迫你在nhibernate 使用它們,并且不會破壞你的架構體系中的任何限制.屬性(attributes)僅僅是純粹的資訊.

使用hbmserializer.validate來啟用/禁用産生的xml流的合法性檢查(依靠nhibernate mapping schema);對于快速查找問題這是很有用的(它們被stringbuilder寫入hbmserializer.error).如果錯誤是這個庫預期的,庫會看它是否是已知的問題并且報告它;解決這些問題能幫助你完成你的解決方案. :)

你的類,字段和屬性properties(成員)可以是私有的;請确認你有使用反射通路私有成員的權限(reflectionpermissionflag.memberaccess).

映射類的成員也會在基類中查找(直到找到映射的基類).是以,你可以在基類(沒有做映射)中修飾成員,然後在它的(做過映射的)子類中使用它.

對于一個有類型(system.type)的name,使用name="xxx"(作為string)設定類型或者設定nametype=typeof(xxx);(給 "name"添加"類型")

預設情況下,.net屬性(attributes)沒有維持屬性(attributes)的順序;是以,你必須自己設定順序,在你管理順序的時候(使用每個屬性的第一個參數).強烈推薦設定它,當你的一個成員上有超過一個屬性(attribute )時.

隻要不産生含糊,你可以在成員上定義很多不相幹的屬性(attributes).一個好的例子是在辨別符成員上的類描述(class-related)屬性(attributes )(類似鑒别器&lt;discriminator&gt;).但是不要忘記管理順序(&lt;discriminator&gt; 必須在&lt;id&gt;的後面).順序來自nhibernate mapping schema中元素(elements)的順序.在我個人看來,我更喜歡在屬性上使用負數(如果它們是在前面的!).

你可以在類上面加 [hibernatemapping] 來指定&lt;hibernate-mapping&gt; 屬性(attributes)(當類被序列化成流時使用).你也可以使用hbmserializer.hbm*屬性(properties)(當被[hibernatemapping]修飾的類型或程式集被序列化時被使用).

不使用一個字元串作為鑒别器值(discriminatorvalue)(在[class]和[subclass]),你可以在任何你需要的對象上這樣使用.例子: [subclass(discriminatorvalueenumformat="d", discriminatorvalueobject=discenum.val1)] 

在這裡,對象是一個枚舉,你可以設定你需要的格式(預設的值是"g").注意你必須把它放在前面!對于其他的類型,隻是簡單的使用了對象的tostring()方法.

如果你使用nullables.nullablexxx類型的的成員(在庫nullables中),系統會自動映射到nullables.nhibernate.nullablexxxtype;不用在[property]中設定type="..."(讓它為空).感謝michael third的這個主意. :)

nhibernate.mapping.attributes産生的每個流都有一個産生日期的注釋;你可以通過方法writedatecomment啟用/禁用它.

如果你忘記提供一個必須的xml屬性(attribute),系統會抛出一個異常,在建立映射時.

映射[component] 時,被推薦的并且最簡單的方式是使用[componentproperty].

首先,放置[component]在元件類并且映射它的字段/屬性.注意不要在[component]設定名字.然後,在你的類的每個成員,添加[componentproperty].但是你不能改變每個成員的存取(access),更新(update)或插入(insert). 

在nhibernate.mapping.attributes.test裡有一個例子(注意compaddress類和他在其他類中的使用). 

注意最後一件事情:componentpropertyattribute是從dynamiccomponentattribute繼承來的,容易把它緊接着寫在 &lt;component&gt;元素的後面,在xml流中.

另一個映射[component]的方式是,它用這種方法讓庫工作:如果一個類包含了一個元件映射,那麼這個元件将會被類包含.nhibernate.mapping.attributes.test包含joinedbaz和stuff使用位址(address)元件的例子. 很簡單的,添加了以後 [component(name = "mycomp")] private class subcomp : comp {}

在所有類中,一個優勢是能夠改變每個成員的存取(access),更新(update)或插入(insert).但是,你必須添加元件子類到每個類中(并且它不能被繼承).

關于自定義。hbmserializer使用hbmwriter序列化各種屬性(attributes)。他的方法是虛的;是以你可以建立一個子類,重寫任何方法(來改變它的預設行為)。

使用屬性(property)hbmserializer.hbmwriter來改變寫的實作者。(你可以設定一個hbmwriter的子類)。使用了部分提示的例子:(0,1和2按順序排列)

産生的:

首先,閱讀源代碼裡面的todos

position屬性(property)被加在所有屬性(attributes)上,用來給他們排序。但是仍然有問題:

當一個父元素"p"有一個子元素"x",它的另一個子元素"c"有子元素"x"。:d 如

在這個例子中,如果這樣寫:

x(3)将會屬于c(1)!(和x(2)一樣)

下面是&lt;dynamic-component&gt;和&lt;nested-composite-element&gt;的情況。

另一個壞消息是,現在,後來加入的xml元素不能被包含.例如:沒有辦法在&lt;dynamic-component&gt;放置集合.原因是nhibernate-mapping-2.0.xsd檔案告訴程式元素怎麼被建立,按照什麼順序被建立,并且nhibernate.mapping.attributes按這個順序使用它們.

總之,解決方案應該添加整型的parentnode屬性(property)給baseattribute,這樣你能夠建立一個真實的情況...

實際上,沒有其他的知識點了而且也沒有計劃好的修改.這個庫将會成為穩定的完整版本;但是你發現了問題或者有有效的改進想法,請聯系我們!

另一個消息,希望有比nhibernate.mapping.attributes.test更好的testfixture.:d

schema (nhibernate-mapping-2.0.xsd)的任何改變意味着:

檢查是否要在generator中做任何改變(象updating knowenums / allowmultiplevalue / isroot / issystemtype / issystemenum / cancontainitself)

更新/src/nhibernate.mapping.attributes/nhibernate-mapping-2.0.xsd (複制/粘貼),并且再次運作generator(即使你沒有修改)

運作測試項目,确定沒有已知的異常抛出.應該在可以確定能夠把握改變帶來的破壞時,修改/添加這個項目中一個類/屬性(property)(=&gt;更新hbm.xml檔案和/或nhibernate.mapping.attributes-1.1.csproj項目的引用)

這個實作基于nhibernate mapping schema;有可能很多"标準schema特性"沒有被支援... 

這個版本的nhibernate.mapping.attributes需要使用nhibernate庫的版本的schema來産生.

這個項目的設計,性能是一個(十分)小的目标,實作和維護則要重要許多.

本文來自《nhibernate 中文文檔》

部落格位址:

<a href="http://www.cnblogs.com/wolf-sun">http://www.cnblogs.com/wolf-sun/</a>

部落格版權:

本文以學習、研究和分享為主,歡迎轉載,但必須在文章頁面明顯位置給出原文連接配接。

如果文中有不妥或者錯誤的地方還望高手的你指出,以免誤人子弟。如果覺得本文對你有所幫助不如【推薦】一下!如果你有更好的建議,不如留言一起讨論,共同進步!

再次感謝您耐心的讀完本篇文章。

轉載:http://www.cnblogs.com/wolf-sun/p/3733929.html