NH3—NHibernate的數據庫映射方式

1、NHibernate的映射方式介紹

當使用Nhibernate做爲咱們的ORM框架時,有四種主要的映射類型:html

一、基於XML的映射。數據庫

二、基於特性的映射。(NHibernate.Mapping.Attributes)c#

三、Fluent映射。(流映射)瀏覽器

四、基於約定的映射,有時也稱爲自動映射。(Fluent NHibernate AutoMapping
app

除了上面說的這四種經常使用的映射方式以外,Nhibernate還提供了不少的映射方式,好比ConfOrm映射,這個想要學習的朋友們本身瞭解一下吧,第一種映射方式網上的資料不少就不作介紹了,之後若是有時間會完善一下這部分,畢竟本身也不是很瞭解,在練習的時候我推薦你們用特性映射和fluent這兩種映射方式,由於比較簡單易上手,實際項目要看需求。
框架


2、Fluent NHibernate映射

2.一、Fluent NHibernate是什麼?

Fluent NHibernate提供了一個方法讓你再也不須要去寫NHibernate的標準映射文件(.hbm.xml),而是能夠把你的映射文件都使用C#來寫。這樣作,方便了咱們的代碼重構,提供了代碼的易讀性,並精簡了項目代碼。工具

2.二、Fluent NHibernate的優勢?

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直接在編譯時就完成。

2.3、Fluent NHibernate方式的寫法和工廠建立

一、在項目中建立存放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):映射模型到數據庫之方式一



3、NHibernate.Mapping.Attributes特性映射

特性映射是我在工做以後接觸到的,這種映射都先經過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
    }
}

二、將映射在工廠建立的時候添加


4、Fluent NHibernate AutoMapping自動映射

我在這說一下這種映射的思路,以後若是有時間我會本博客中添加代碼事例。

一、對poco實體要繼承一個BaseEntity類(裏面是Id和一些通用的東西)

二、指定要自動映射的程序集,用法就是IsSubclassOf(typeof(BaseEntity))

三、定義各類Convention(約定)

四、添加這些約定要一個集合並在建立SessionFactory的時候調用

對於這種映射方式你們能夠再瀏覽器中搜索「Fluent NHibernate automapping」會出來不少內容(記得多看幾頁,不要只看第一頁的內容。我挑選出兩邊比較好的博客給你們,第一篇博客比較容簡單易懂,第二篇屬於進階,代碼比較全。你們看完以後基本的就會了,有不少用法和屬性還須要本身多查一些資料。

Fluent NHibernate AutoMapping Conventions

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

相關文章
相關標籤/搜索