當使用Nhibernate做爲咱們的ORM框架時,有四種主要的映射類型:html
一、基於XML的映射。數據庫
二、基於特性的映射。(NHibernate.Mapping.Attributes)c#
三、Fluent映射。(流映射)瀏覽器
四、基於約定的映射,有時也稱爲自動映射。(Fluent NHibernate AutoMapping)
app
除了上面說的這四種經常使用的映射方式以外,Nhibernate還提供了不少的映射方式,好比ConfOrm映射,這個想要學習的朋友們本身瞭解一下吧,第一種映射方式網上的資料不少就不作介紹了,之後若是有時間會完善一下這部分,畢竟本身也不是很瞭解,在練習的時候我推薦你們用特性映射和fluent這兩種映射方式,由於比較簡單易上手,實際項目要看需求。
框架
Fluent NHibernate提供了一個方法讓你再也不須要去寫NHibernate的標準映射文件(.hbm.xml),而是能夠把你的映射文件都使用C#來寫。這樣作,方便了咱們的代碼重構,提供了代碼的易讀性,並精簡了項目代碼。工具
NHibernate就不用說了,你們都知道是一個好的ORM工具,它的mapping都是以XML格式定義的。每一個類都有一個mapping文件映射到數據庫對應的表。 Fluent NHibernate取消了這些xml文件。學習
爲何要取代XML文件呢?ui
a.XML不是實時編譯的。當你的XML配置文件有錯誤時,你只有在運行時才能看到哪裏出錯。spa
b.XML是很是繁瑣的。的確在NHibernate中的配置文件,xml節點很是簡單,可是仍然掩蓋不了XML文件自己的繁瑣性。
c.映射文件中重複的屬性設置。好比在xml中咱們須要設置每一個string類型的字段都不容許爲空,長度大於1000,int型都得有個默認值爲-1,這樣最終的xml配置文件你會發現有不少的重複工做。
Fluent NHibernate如何克服這些缺陷呢?
Fluent NHibernate把這些配置爲文件都轉化爲了C#代碼,這樣可讓你的mapping直接在編譯時就完成。
一、在項目中建立存放Poco的Entities和存放映射的Mappings文件夾
二、Poco類仍是普通的寫法,用Fluent的繼承,還有三種關係我會在下一篇博客中單說,這裏先簡單介紹
using System; namespace BAT.APT.Domain.Entities { public class Product { public virtual int Id { get; set; } public virtual string Name { get; set; } public virtual decimal Price { get; set; } public virtual DateTime CreateTime { get; set; } public virtual string Del { get; set; } } }
三、寫映射的mapping。全部的mapping類都要繼承自ClassMap<>
using System; using BAT.APT.Domain.Entities; using FluentNHibernate.Mapping; namespace BAT.APT.Domain.Maps { public class ProductMap:ClassMap<Product> { public ProductMap() { Table("product"); Id(m => m.Id, "Product_Id"); Map(m => m.Name); Map(m => m.Price).Column("Price"); Map(m => m.CreateTime); Map(m => m.Del); //Not.LazyLoad();FluentNh默認是延遲加載的,寫上這句話就不是延遲加載了 } } }
四、將映射在工廠建立的時候添加進去,能夠單一文件添加也能夠用反射將程序集添加,他會自動識別繼承自ClassMap類的類
private static ISessionFactory CreateSessionFactory() { //3fluent調用外部配置文件中的文件,我在配置的時候發現,只要nh文件的屬性是始終複製,他就會在bin文件中出現能夠找到 return Fluently.Configure(new NHibernate.Cfg.Configuration().Configure("hibernate.cfg.xml"))//上面這是連接數據庫用的 .Mappings(m => m.FluentMappings .AddFromAssembly(System.Reflection.Assembly.Load("BAT.APT.Domain")).ExportTo(@"E:\Mapping")) .BuildSessionFactory(); }
五、map文件中的方法詳細使用能夠參考這篇文章
NHibernate初學者指南(5):映射模型到數據庫之方式一
特性映射是我在工做以後接觸到的,這種映射都先經過PD建立數據庫模型,而後建立數據庫,在Poco類上打上特性標籤,就能夠和數據庫進行映射了
Nhibernate拒絕配置文件(NHibernate.Mapping.Attributes的使用)
一、這種映射方式直接在Poco類上打標籤
引入命名空間 namespace PCITC.MES.EAM.Poco.ProfessionalManagement { [Class(Table = "eam_pro_sealed_management_t")] [Component(Name = "SealedManagement")] public class SealedManagement { /// <summary> /// ID /// </summary> [Id(0, TypeType = typeof(long), Name = "Id", UnsavedValue = "0")] [Column(1, Name = "ID", NotNull = true, SqlType = "number")] [Generator(2, Class = "sequence")] [Param(3, Name = "sequence", Content = "s_eam_pro_sealed_management")] public virtual long Id { get; set; } /// <summary> /// 計數鍵值/ID /// </summary> [Property(Column = "countkey_id")] public virtual long CountKeyId { get; set; } /// <summary> /// 密封點數 /// </summary> [Property(Column = "sealpoints_count")] public virtual long SealPointsCount { get; set; } /// <summary> /// 登記日期 /// </summary> [Property(Column = "registration_date")] public virtual DateTime RegistrationDate { get; set; } /// <summary> /// 登記人 /// </summary> [Property(Column = "registration_people")] public virtual string RegistrationPeople { get; set; } /// <summary> /// 上次修改時間 /// </summary> [Property(Column = "last_modified_date")] public virtual DateTime? LastModifiedDate { get; set; } /// <summary> /// 上次修改人 /// </summary> [Property(Column = "last_modified_people")] public virtual string LastModifiedPeople { get; set; } /// <summary> /// 上次備註 /// </summary> [Property(Column = "last_remark")] public virtual string LastRemark { get; set; } /// <summary> /// 密封類型Id /// </summary> [Property(Column = "seal_type_id")] public virtual long SealTypeId { get; set; } /// <summary> /// 包含刪除 /// </summary> [Property(Column = "del")] public virtual long Del { get; set; } /// <summary> /// 裝置Id /// </summary> [Property(Column = "equip_func_place_id")] public virtual long EquipFuncPlaceId { get; set; } /// <summary> /// 設備種類Id /// </summary> [Property(Column = "equip_type_id")] public virtual long EquipTypeId { get; set; } /// <summary> /// 裝置區域Id /// </summary> [Property(Column = "equip_area_id")] public virtual long? EquipAreaId { get; set; } /// <summary> /// 維護工廠Id /// </summary> [Property(Column = "maintain_factory_id")] public virtual long? MaintainFactoryId { get; set; } /// <summary> /// 計劃工廠Id /// </summary> [Property(Column = "plan_factory_id")] public virtual long? PlanFactoryId { get; set; } /// <summary> /// 部門中心Id /// </summary> [Property(Column = "department_center_id")] public virtual long? DepartmentCenterId { get; set; } #region 外鍵 /// <summary> /// 裝置 /// </summary> //[ManyToOne(Name = "EquipFuncPlace", Lazy = Laziness.Proxy,NotFound = NotFoundMode.Ignore, ClassType = typeof(EquipFuncPlace), Column = "equip_func_place_id", Unique = false, Insert = false, Update = false)] //public virtual EquipFuncPlace EquipFuncPlace { get; set; } [ManyToOne(0, ClassType = typeof(EquipFuncPlace), Column = "EquipFuncPlaceId", OuterJoin = OuterJoinStrategy.True, Lazy = Laziness.Proxy,NotFound = NotFoundMode.Ignore, Cascade = "none", Insert = false, Update = false)] public virtual EquipFuncPlace EquipFuncPlace { get; set; } /// <summary> /// 密封類型:在字典表中定義 /// </summary> [ManyToOne(0, ClassType = typeof(SysDictSub), Column = "SealTypeId", OuterJoin = OuterJoinStrategy.True, Lazy = Laziness.Proxy,NotFound = NotFoundMode.Ignore, Cascade = "none", Insert = false, Update = false)] public virtual SysDictSub SysDictSubEntityBySealType { get; set; } /// <summary> /// 設備種類:在字典表中定義 /// </summary> [ManyToOne(0, ClassType = typeof(SysDictSub), Column = "EquipTypeId", OuterJoin = OuterJoinStrategy.True, Lazy = Laziness.Proxy,NotFound = NotFoundMode.Ignore, Cascade = "none", Insert = false, Update = false)] public virtual SysDictSub SysDictSubEntityByEquipType { get; set; } /// <summary> /// 裝置區域:在字典表中定義 /// </summary> [ManyToOne(0, ClassType = typeof(SysDictSub), Column = "EquipAreaId", OuterJoin = OuterJoinStrategy.True, Lazy = Laziness.Proxy,NotFound = NotFoundMode.Ignore, Cascade = "none", Insert = false, Update = false)] public virtual SysDictSub SysDictSubEntityByEquipArea { get; set; } /// <summary> /// 維護工廠 /// </summary> [ManyToOne(0, ClassType = typeof(BaseFactory), Column = "MaintainFactoryId", OuterJoin = OuterJoinStrategy.True, Lazy = Laziness.Proxy,NotFound = NotFoundMode.Ignore, Cascade = "none", Insert = false, Update = false)] public virtual BaseFactory MaintainFactory { get; set; } ///// <summary> ///// 部門中心 ///// </summary> //[ManyToOne(0, ClassType = typeof(MESWorkShop), Column = "MesWorkShopId", OuterJoin = OuterJoinStrategy.True, Lazy = Laziness.Proxy,NotFound = NotFoundMode.Ignore, Cascade = "none", Insert = false, Update = false)] //public virtual MESWorkShop MesWorkShop { get; set; } #endregion } }
二、將映射在工廠建立的時候添加
我在這說一下這種映射的思路,以後若是有時間我會本博客中添加代碼事例。
一、對poco實體要繼承一個BaseEntity類(裏面是Id和一些通用的東西)
二、指定要自動映射的程序集,用法就是IsSubclassOf(typeof(BaseEntity))
三、定義各類Convention(約定)
四、添加這些約定要一個集合並在建立SessionFactory的時候調用
對於這種映射方式你們能夠再瀏覽器中搜索「Fluent NHibernate automapping」會出來不少內容(記得多看幾頁,不要只看第一頁的內容。我挑選出兩邊比較好的博客給你們,第一篇博客比較容簡單易懂,第二篇屬於進階,代碼比較全。你們看完以後基本的就會了,有不少用法和屬性還須要本身多查一些資料。