ABP 基础设施层——集成 NHibernate

本文翻译自ABP的官方教程《NHibernate Integration》,地址为:http://aspnetboilerplate.com/Pages/Documents/NHibernate-Integration

ABP可以与任何ORM框架协同工作,它内置了对NHibernate的集成支持。本文将介绍如何在ABP中使用NHibernate。本文假定你已经初步掌握了NHibernate。

译者注:怎么才算初步掌握了NHibernate呢?译者认为应当懂得使用NHibernate进行CRUD,懂得使用Fluent模式进行映射。

1 Nuget包

要在ABP中使用NHibernate作为ORM框架的话,需要到Nuget上下载一个名为Abp. NHibernate的包。比较好的做法是:新建一个独立的程序集(dll),然后在这个程序集中调用这个包和NHibernate。

2 配置(Configuration)

要使用Nhibernate,首先要对它进行配置,配置的方法是在模块的PreInitialize方法中编写配置代码,如下所示:

 [DependsOn(typeof(AbpNHibernateModule))]
public class SimpleTaskSystemDataModule : AbpModule
{
public override void PreInitialize()
{
var connStr = ConfigurationManager.ConnectionStrings["Default"].ConnectionString;
Configuration.Modules.AbpNHibernate().FluentConfiguration
.Database(MsSqlConfiguration.MsSql2008.ConnectionString(connStr))
.Mappings(m => m.FluentMappings.AddFromAssembly(Assembly.GetExecutingAssembly()));
}
public override void Initialize()
{
IocManager.RegisterAssemblyByConvention(Assembly.GetExecutingAssembly());
}
}

ABP之所以能与Nhibernate协同工作,是因为内置的AbpNHibernateModule模块提供了必要的适配器。

    (1)实体映射(Entity mapping

在下面的示例中,我们使用Fluent映射模式来对所有的实体类进行映射:

public class TaskMap : EntityMap<Task>
{
public TaskMap()
: base("TeTasks")
{
References(x => x.AssignedUser).Column("AssignedUserId").LazyLoad();
Map(x => x.Title).Not.Nullable();
Map(x => x.Description).Nullable();
Map(x => x.Priority).CustomType<TaskPriority>().Not.Nullable();
Map(x => x.Privacy).CustomType<TaskPrivacy>().Not.Nullable();
Map(x => x.State).CustomType<TaskState>().Not.Nullable();
}
}

EntityMap类是ABP中的一个内置类,它派生自ClassMap<T>类,可以自动地对Id属性进行映射,并且在构造函数中获取表名。在上例中我们从EntityMap中派生,然后使用FluentNHibernate来映射其它属性。当然,你也可以直接从ClassMap中派生。在ABP中,你可以使用FluentNHibernate中定义的所有API。

在上例中我们使用了Fluent映射模式,你也可以使用其它映射模式,比如基于xml文件的映射模式。

译者注:Nhibernate有四种映射模式:(1)基于XML的映射。(2)基于特性的映射。(3)Fluent映射。(4)基于约定的映射,也称为自动映射。

3 仓储实现(Repository implementation)

如果需求比较简单的话,你甚至不需要创建单独的仓储类,直接使用仓储的默认实现即可。如果实在需要创建单独的仓储类的话,建议从NhRepositoryBase中派生。

    (1默认实现(Default implementation)

如果你只想使用预定义的仓储方法的话,你甚至不需要为实体创建单独的仓储类。如下所示:

public class PersonAppService : IPersonAppService
{
private readonly IRepository<Person> _personRepository;
public PersonAppService(IRepository<Person> personRepository)
{
_personRepository = personRepository;
} public void CreatePerson(CreatePersonInput input)
{
person = new Person { Name = input.Name, EmailAddress = input.EmailAddress };
_personRepository.Insert(person);
}
}

PersonAppService类采用构造函数注入的方式注入了一个IRepository<Person>对象,然后调用了预定义的Insert方法。采用这种方式,你可以方便地注入IRepository<TEntity> (或者IRepository<TEntity, TPrimaryKey>)对象,然后调用预定义的方法。请查看仓储文档以获得预定义方法的列表。

   (2)自定义仓储(Custom repositories

如果你想添加自定义方法,最佳的作法是,首先将它添加到仓储接口中,然后在仓储类中实现。ABP提供了一个名为NhRepositoryBase的基类,这使得实现仓储变得简单快捷,要实现IRepository接口,只需要从这个基类中派生。

假定我们有一个名为Task的实体,它可以被赋予Person实体。Task有一个State属性(值为新建、已分配、已完成等)。我们需要编写一个自定义方法,这个方法能根据某些条件获取Task列表,并且使得Task的AssisgnedPerson属性可以在一次数据库查询中被加载(使用NHibernate的立即加载方法Fetch)。如下所示:

public interface ITaskRepository : IRepository<Task, long>
{
List<Task> GetAllWithPeople(int? assignedPersonId, TaskState? state);
} public class TaskRepository : NhRepositoryBase<Task, long>, ITaskRepository
{
public TaskRepository(ISessionProvider sessionProvider)
: base(sessionProvider)
{ } public List<Task> GetAllWithPeople(int? assignedPersonId, TaskState? state)
{
var query = GetAll();
if (assignedPersonId.HasValue)
{
query = query.Where(task => task.AssignedPerson.Id == assignedPersonId.Value);
} if (state.HasValue)
{
query = query.Where(task => task.State == state);
} return query
.OrderByDescending(task => task.CreationTime)
.Fetch(task => task.AssignedPerson)
.ToList();
}
}

预定义方法GetAll()返回了一个IQueryable<Task>对象,接着我们将参数放入到Where筛选器中,最后调用ToList()来获得一个Task列表。

此外,你可以通过调用base.Session属性来获得一个Session对象,这样一来,你就可以直接使用NHibernate的所有功能。

仓储类应当在构造函数中获取ISessionProvider对象。通过这种方式,在单元测试的时候,我们可以很容易地注入一个虚拟的 Session Provider 对象;而在运行的时候, ABP 会根据配置注入相应的 Session Provider对象。

    (3)应用程序专用的仓储基类(Application specific base repository class

要实现仓储类,只需要从NhRepositoryBase中派生即可。但是更好的做法是,自定义一个派生自NhRepositoryBase的基类,然后在这个基类中添加一些通用的方法。这样做的好处是,所有派生自这个基类的仓储都继承了这些通用方法。

// 应用程序中的所有仓储的基类

public abstract class MyRepositoryBase<TEntity, TPrimaryKey> : NhRepositoryBase<TEntity, TPrimaryKey>
where TEntity : class, IEntity<TPrimaryKey>
{
protected MyRepositoryBase(ISessionProvider sessionProvider)
: base(sessionProvider)
{ } // 添加仓储基类的通用方法
} //为所有拥有整型 Id 的实体添加一个快捷方式 public abstract class MyRepositoryBase<TEntity> : MyRepositoryBase<TEntity, int>
where TEntity : class, IEntity<int>
{
protected MyRepositoryBase(ISessionProvider sessionProvider)
: base(sessionProvider)
{ } // 不 要 在 这 里 添 加 任 何 通 用 方 法 ,通 用 方 法 应 当 被添加到 上 面 的 基 类 中(MyRepositoryBase<TEntity, TPrimaryKey>)
} public class TaskRepository : MyRepositoryBase<Task>, ITaskRepository
{
public TaskRepository(ISessionProvider sessionProvider)
: base(sessionProvider)
{ } // 添加本仓储类的专用方法 }
 
分类: 架构
标签: Abp

集成 NHibernate的更多相关文章

  1. ABP 基础设施层——集成 NHibernate

    本文翻译自ABP的官方教程<NHibernate Integration>,地址为:http://aspnetboilerplate.com/Pages/Documents/NHibern ...

  2. spring.net 集成nhibernate配置文件(这里暴露了GetCurrentSession 对于 CurrentSession unbond thread这里给出了解决方法)

    我这里主要分成了两个xml来进行spring.net管理实际情况中可自己根据需要进行分类 Dao2.xml <?xml version="1.0" encoding=&quo ...

  3. ABP官方文档翻译 9.3 NHibernate集成

    NHibernate集成 Nuget包 配置 实体映射 仓储 默认实现 自定义仓储 应用程序特定基础仓储类 ABP可以使用任何ORM框架,它内置集成NHibernate.此文档将讲解ABP如何使用NH ...

  4. NHibernate框架与BLL+DAL+Model+Controller+UI 多层架构十分相似--『Spring.NET+NHibernate+泛型』概述、知识准备及介绍(一)

    原文://http://blog.csdn.net/wb09100310/article/details/47271555 1. 概述 搭建了Spring.NET+NHibernate的一个数据查询系 ...

  5. ABP框架 - 仓储

    文档目录 本节内容: 默认仓储 自定义仓储 自定义仓储接口 自定义仓储实现 基仓储方法 查询 获取单个实体 获取实体列表 关于 IQueryable 自定义返回值 插入 更新 删除 其它 关于异步方法 ...

  6. 【转】Spring.NET学习笔记——目录

    目录 前言 Spring.NET学习笔记——前言 第一阶段:控制反转与依赖注入IoC&DI Spring.NET学习笔记1——控制反转(基础篇) Level 200 Spring.NET学习笔 ...

  7. Spring.NET学习

    Spring.NET学习笔记——目录(原)   目录 前言 Spring.NET学习笔记——前言 第一阶段:控制反转与依赖注入IoC&DI Spring.NET学习笔记1——控制反转(基础篇) ...

  8. ABP框架系列之三十八:(NHibernate-Integration-NHibernate-集成)

    ASP.NET Boilerplate can work with any O/RM framework. It has built-in integration with NHibernate. T ...

  9. Spring.NET依赖注入框架学习--简介

    Spring.NET依赖注入框架学习--Spring.NET简介 概述 Spring.NET是一个应用程序框架,其目的是协助开发人员创建企业级的.NET应用程序.它提供了很多方面的功能,比如依赖注入. ...

随机推荐

  1. PM俱乐部之旅7-弱活着

     有些人认为,最终我们放松一点时间,有意想不到的事情发生--公司组织结构调整. 公司由于业务范围调整,所以要进行对应的组织结构调整.PMO部门也随之重组,项目经理俱乐部的活动改成项目交流会,请项目 ...

  2. WindowsPhone 在 根据公历 获取月球日期数据

    WindowsPhone 在 根据公历 获取月球日期数据 WindowsPhone 在 它们的定义 类,根据公历 获取月球日期数据 using System; using System.Collect ...

  3. abstract修改方法

    abstract这种方法修饰,主要用在抽象类和抽象方法. 抽象的类是不可实例化的比如 public abstract class Test{ } 他能够含有抽象的方法 public abstract ...

  4. Java调用Lua(转)

    Java 调用 Lua app发版成本高,覆盖速度慢,覆盖率页低.一些策略上的东西如果能够从服务端控制会方便一些.所以考虑使用Lua这种嵌入式语言作为策略实现,Java则是宿主语言. 总体上看是一个模 ...

  5. 【原创翻译】认识MVC设计模式:web应用开发的基础(实际编码篇)

    原文地址:http://www.larryullman.com/2009/10/15/understanding-mvc-part-3/ 全系列INDEX [原创翻译]认识MVC设计模式:web应用开 ...

  6. 80x86汇编小站站长简单介绍-2014年08月23日

    [序言] 旧版的"80x86汇编小站站长简单介绍"已经过时了, 因此于2013年10月01日花费1个小时又一次更新和排版一次. [人生格言]  1] 一生都用头脑而不是情绪解决这个 ...

  7. 10令人惊叹的模型的影响HTML5应用程序及源代码

    HTML5已经越来越流行起来了.尤其是移动互联网的发展,更是带动了HTML5的迅猛发展,我们也是时候学习HTML5了,以防到时候落伍.今天给大家介绍10款效果惊艳的HTML5应用.方便大家学习,也将应 ...

  8. JAVA经BigDecimal圆角的解决方案及注意事项

    /** * @Description: 四舍五入住宿2小数位数 * @param valueName * @return */ public static Double formateDouble45 ...

  9. c#中的属性

    在C#中我们可以很自由的访问共有字段,但有时我们可能需要某字段只能读或者写,或在改变字段值得时候做一些其他事情,显然这些仅仅依靠字段是无法实现的,于是便有了属性. 1.基本用法 c#中的属性由属性作用 ...

  10. 的无线通信网络的学习LTE的关键技术HARQ(20141217)

    今天,我们就来一起看一下LTE申请的关键技术HARQ(自己主动混合重传技术) 因为在信道传输过程中的信息,它会产生信息丢失,因此,为了维持的信息的完整性.总是有重发信息,完成所有的迄今收到的资料. 首 ...