[NHibernate]使用AttributeNHibernate.Mapping.Attributes

來源:互聯網
上載者:User

標籤:style   blog   class   code   c   java   

系列文章

[Nhibernate]體繫結構

[NHibernate]ISessionFactory配置

[NHibernate]持久化類(Persistent Classes)

[NHibernate]O/R Mapping基礎

[NHibernate]集合類(Collections)映射 

[NHibernate]關聯映射

[NHibernate]Parent/Child

[NHibernate]緩衝(NHibernate.Caches)

什麼是NHibernate.Mapping.Attributes?

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 ),例如:

1 [NHibernate.Mapping.Attributes.Class]2     public class Example3     {4         [NHibernate.Mapping.Attributes.Property]5         public string Name;6     }

完成這個步驟後,使用NHibernate.Mapping.Attributes.HbmSerializer:(這裡我們使用了Default ,它是一個執行個體,在你不必須/不想自己建立它時使用).

 1  System.IO.MemoryStream stream = new System.IO.MemoryStream(); // where the xml will be written 2     NHibernate.Mapping.Attributes.HbmSerializer.Default.Validate = true; // Enable validation (可選) 3     // Here, we serialize all decorated classes (but you can also do it class by class) 4     NHibernate.Mapping.Attributes.HbmSerializer.Default.Serialize( 5         stream, System.Reflection.Assembly.GetExecutingAssembly() ); 6     stream.Position = 0; // Rewind 7     NHibernate.Cfg.Configuration cfg = new NHibernate.Cfg.Configuration(); 8     cfg.Configure(); 9     cfg.AddInputStream(stream); // Use the stream here10     stream.Close();11     // Now you can use this configuration to build your SessionFactory...

注意:正如你所見: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 )(類似鑒別器<discriminator>).但是不要忘記管理順序(<discriminator> 必須在<id>的後面).順序來自NHibernate mapping schema中元素(elements)的順序.在我個人看來,我更喜歡在屬性上使用負數(如果它們是在前面的!).
  • 你可以在類上面加 [HibernateMapping] 來指定<hibernate-mapping> 屬性(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繼承來的,容易把它緊接著寫在 <component>元素的後面,在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按順序排列)

1  [NHibernate.Mapping.Attributes.Id(0, TypeType=typeof(int))] // Don‘t put it after [ManyToOne] !!!2         [NHibernate.Mapping.Attributes.Generator(1, Class="uuid.hex")]3     [NHibernate.Mapping.Attributes.ManyToOne(2, ClassType=typeof(Foo), OuterJoin=OuterJoinStrategy.True)]4     private Foo Entity;

產生的:

1  <id type="Int32">2         <generator class="uuid.hex" />3     </id>4     <many-to-one name="Entity" class="Namespaces.Foo, SampleAssembly" outer-join="true" />
已知的問題和TODOs

首先,閱讀原始碼裡面的TODOs

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

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

1  <p>2         <c>3             <x />4         </c>5         <x />6     </p>

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

1  [Attributes.P(0)]2         [Attributes.C(1)]3             [Attributes.X(2)]4         [Attributes.X(3)]5     public MyType MyProperty;

X(3)將會屬於C(1)!(和X(2)一樣)

下面是<dynamic-component>和<nested-composite-element>的情況。

另一個壞訊息是,現在,後來加入的XML元素不能被包含.例如:沒有辦法在<dynamic-component>放置集合.原因是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)(=>更新hbm.xml檔案和/或NHibernate.Mapping.Attributes-1.1.csproj項目的引用)

這個實現基於NHibernate mapping schema;有可能很多"標準schema特性"沒有被支援...
這個版本的NHibernate.Mapping.Attributes需要使用NHibernate庫的版本的schema來產生.
這個項目的設計,效能是一個(十分)小的目標,實現和維護則要重要許多.

本文來自《NHibernate 中文文檔》

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.