文档章节

NH3—NHibernate的数据库映射方式

龙马行空
 龙马行空
发布于 2015/01/30 21:44
字数 1860
阅读 158
收藏 0

一、NHibernate的映射方式介绍

当使用Nhibernate作为我们的ORM框架时,有四种主要的映射类型:

1、基于XML的映射。

2、基于特性的映射。(NHibernate.Mapping.Attributes)

3、Fluent映射。(流映射)

4、基于约定的映射,有时也称为自动映射。(Fluent NHibernate AutoMapping

除了上面说的这四种常用的映射方式之外,Nhibernate还提供了很多的映射方式,比如ConfOrm映射,这个想要学习的朋友们自己了解一下吧,第一种映射方式网上的资料很多就不做介绍了,以后如果有时间会完善一下这部分,毕竟自己也不是很了解,在练习的时候我推荐大家用特性映射和fluent这两种映射方式,因为比较简单易上手,实际项目要看需求。


二、Fluent NHibernate映射

2.1、Fluent NHibernate是什么?

Fluent NHibernate提供了一个方法让你不再需要去写NHibernate的标准映射文件(.hbm.xml),而是可以把你的映射文件都使用C#来写。这样做,方便了我们的代码重构,提供了代码的易读性,并精简了项目代码。

2.2、Fluent NHibernate的优点?

NHibernate就不用说了,大家都知道是一个好的ORM工具,它的mapping都是以XML格式定义的。每个类都有一个mapping文件映射到数据库对应的表。 Fluent NHibernate取消了这些xml文件。

为什么要取代XML文件呢?

a.XML不是实时编译的。当你的XML配置文件有错误时,你只有在运行时才能看到哪里出错。

b.XML是非常繁琐的。的确在NHibernate中的配置文件,xml节点非常简单,但是仍然掩盖不了XML文件本身的繁琐性。

c.映射文件中重复的属性设置。比如在xml中我们需要设置每个string类型的字段都不允许为空,长度大于1000,int型都得有个默认值为-1,这样最终的xml配置文件你会发现有很多的重复工作。

Fluent NHibernate如何克服这些缺陷呢?

Fluent NHibernate把这些配置为文件都转化为了C#代码,这样可以让你的mapping直接在编译时就完成。

2.3、Fluent NHibernate方式的写法和工厂创建

1、在项目中创建存放Poco的Entities和存放映射的Mappings文件夹

2、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; } 
    }
}

3、写映射的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默认是延迟加载的,写上这句话就不是延迟加载了
        }
    }
}


4、将映射在工厂创建的时候添加进去,可以单一文件添加也可以用反射将程序集添加,他会自动识别继承自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();
}



5、map文件中的方法详细使用可以参考这篇文章

NHibernate初学者指南(5):映射模型到数据库之方式一



三、NHibernate.Mapping.Attributes特性映射

特性映射是我在工作之后接触到的,这种映射都先通过PD创建数据库模型,然后创建数据库,在Poco类上打上特性标签,就可以和数据库进行映射了

Nhibernate拒绝配置文件(NHibernate.Mapping.Attributes的使用)       


1、这种映射方式直接在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
    }
}

2、将映射在工厂创建的时候添加


四、Fluent NHibernate AutoMapping自动映射

我在这说一下这种映射的思路,之后如果有时间我会本博客中添加代码事例。

1、对poco实体要继承一个BaseEntity类(里面是Id和一些通用的东西)

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

3、定义各种Convention(约定)

4、添加这些约定要一个集合并在创建SessionFactory的时候调用

对于这种映射方式大家可以再浏览器中搜索“Fluent NHibernate automapping”会出来很多内容(记得多看几页,不要只看第一页的内容。我挑选出两边比较好的博客给大家,第一篇博客比较容简单易懂,第二篇属于进阶,代码比较全。大家看完之后基本的就会了,有很多用法和属性还需要自己多查一些资料。

Fluent NHibernate AutoMapping Conventions

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



































© 著作权归作者所有

龙马行空
粉丝 390
博文 127
码字总数 119251
作品 0
房山
前端工程师
私信 提问
NHibernate从入门到精通系列(1)——NHibernate概括

内容摘要 NHibernate简介 ORM简介 NHibernate优缺点 一、NHibernate简介 什么是?NHibernate?NHibernate是一个面向.NET环境的对象/关系数据库映射工具。对象/关系数据库映射(object/relati...

长平狐
2012/06/11
576
0
NHibernate 5.0 发布,对象关系映射解决方案

NHibernate 是一个基于.Net 的针对关系型数据库的对象持久化类库。Nhibernate 来源于非常优秀的基于Java的Hibernate 关系型持久化工具。NHibernate 从数据库底层来持久化你的.Net 对象到关系...

周其
2017/10/16
1K
6
C#——Nhibernate探索

C#—Nhibernate探索 本篇文章,让我们一起来探索Nhibernate。 首先我们去搜索Nhibernate下载地址,如下链接所示。 该版本可能是最新版,我下载的4.0.4.GA。其中GA意思我没搞清楚。不过应该不...

kiba518
2018/07/16
0
0
Nhibernate 3.00

发布 刚刚NHibernate的Leader——Fabio Maulo发布了NHibernate 3.0.0.Alpha1版本,这是NHibernate 3.0.0的第一个公开测试版本。 下载地址 你可以到这里下载NHibernate 3.0.0.Alpha1,基于.Ne...

李永波
2010/08/05
0
1
NHibernate 快速入门

这篇教程将透过你的第一个NHibernate项目,讲述配置和映射所需要的基本步骤。 仅关注我们想要的,我们将从一个很简单的例子开始。为了让代码量最小,我们也去掉了单元测试和接口的代码,专一...

徐继开
2013/07/12
15.7K
25

没有更多内容

加载失败,请刷新页面

加载更多

为什么加个注解@Transtaional就可以保证事务的一致性和完整性?

<?xml version="1.0" encoding="UTF-8"?><beans xmlns="http://www.springframework.org/schema/beans"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xmlns:context="http:......

architect刘源源
33分钟前
2
0
硅谷对于禁华为坐立不安

5 月 15 日,美国商务部决定把华为及其多家关联公司列入一份“实体名单”后,20 日又宣布给与华为 90 天“临时执照”,为“依赖华为设备的美国通信商留出余地”。 尽管目前给出了“临时执照”...

linuxCool
今天
3
0
Java—System类入门学习

第三阶段 JAVA常见对象的学习 System类 System类包含一些有用的字段和方法,他不能被实例化 //用于垃圾回收public static void gc()//终止正在运行的java虚拟机。参数用作状态码,根据惯例...

BWH_Steven
今天
6
0
OSChina 周日乱弹 —— 喝了维他茶,忘了那个她

Osc乱弹歌单(2019)请戳(这里) 【今日歌曲】 @xiaoniezi :#今日歌曲推荐#哈哈哈洗脑《土拨鼠之歌》 《土拨鼠之歌》 手机党少年们想听歌,请使劲儿戳(这里) 周六…… 不是该休息么, 被...

小小编辑
今天
639
11
你需要知道的 5 个 Linux 新手会犯的失误

Linux 爱好者们分享了他们犯下的一些最大错误。 终身学习是明智的 —— 它可以让你的思维敏捷,让你在就业市场上更具竞争力。但是有些技能比其他技能更难学,尤其是那些小菜鸟错误,当你尝试...

xiangyunyan
今天
21
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部