返回总目录


本篇目录

ABP可以使用任何ORM框架工作,并且已经内置了NHibernate集成。这篇文章会解释如何在ABP中使用NHibernate。阅读本文的前提是假设你已经熟悉了EF的基本知识。

Nuget包###

在ABP中使用NH作为ORM的Nuget包是Abp.NHibernate。你应该将它添加到应用程序中。最好在应用程序中分离的程序集(dll)中实现NHibernate,并让该程序集依赖Abp.NHibernate包。

配置###

要开始使用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());
}
}

AbpNHibernate模块为了使ABP能够使用NHibernate工作提供了基本的功能和适配器。

实体映射

在下面的样例配置中,使用了当前程序集中的所有映射类进行了流畅地映射。一个映射类的例子如下所示:

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的一个类,它会自动映射 Id属性并在构造函数中获得表名。因此,我们可以从它派生并使用 FluentNHibernate映射其他的属性。当然,你可以直接从ClassMap派生,可以使用FluentNHibernate的所有API,也可以使用NHinernate其他的映射技术(比如映射XML文件)。

仓储###

你可以使用仓储的默认实现而不用在项目中创建仓储类。或者可以创建派生自NhRepositoryBase的仓储类。

仓储基类

虽然可以从ABP的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)
{
} //不要在这里添加任何方法,在上面的方法中添加(因为该方法继承了上面的方法)
} public class TaskRepository : MyRepositoryBase<Task>, ITaskRepository
{
public TaskRepository(ISessionProvider sessionProvider)
: base(sessionProvider)
{
} //这里添加一些task仓储特有的方法
}

默认实现

你不需要为实体类创建仓储,只需要使用预定义的仓储方法。例子:

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并使用仓储中的Insert方法。使用这种方法,你可以轻松地注入 IRepository(或者IRepository<TEntity,TPrimaryKey>),然后使用预定义的方法。所有预定义的方法列表,请查看仓储文档

自定义仓储方法

如果你想添加一些自定义的方法,那么首先应该给它添加仓储接口(这是最佳实践),然后在仓储类中实现。ABP提供了一个基类NhRepositoryBase来轻松地实现仓储。要实现仓储接口,只需要从仓储基类中派生仓储就可以了。

假设我们有一个Task(任务)实体,该任务可以派给一个Person(人)实体,而且Task实体有这么几种状态,包括new,assigned,completed等等。我们可能需要写一个自定义方法来根据一些条件和AssignedPerson来获取任务的列表。看下面的代码:

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,然后使用给定的参数添加了一些 Where过滤。最后使用 ToList()获得Tasks的列表。

你也可以在仓储方法中使用Session对象来调用NHibernate的全部API。

仓储应该在它的构造函数中获得一个ISessionProvider。这样的话,我们就可以在单元测试中轻松地注入一个伪造的session提供者了。在运行时,ABP会自动地注入正确的session提供者。

阅读其他###

你也可以查看仓储文档获取更多关于仓储的知识。

ABP理论学习之NHibernate集成的更多相关文章

  1. ABP理论学习之SignalR集成

    返回总目录 本篇目录 介绍 安装 建立连接 内置功能 你自己的SignaR代码 介绍 Abp.Web.SignalR 使得在基于ABP的应用程序中使用 SignalR相当容易.查看SignalR文档获 ...

  2. ABP理论学习之EntityFramework集成

    返回总目录 本篇目录 Nuget包 创建DbContext 仓储 仓储基类 实现仓储 自定义仓储方法 阅读其他 ABP可以使用任何ORM框架工作,并且已经内置了EntityFramework集成.这篇 ...

  3. ABP理论学习之OWIN集成

    返回总目录 如果你的应用中使用了OWIN,那么需要在主项目(一般来说是指Web项目)中添加Abp.Owin的nuget包,然后像下面那样在OWIN的 Startup文件中调用 UseAbp()扩展方法 ...

  4. ABP理论学习之OData集成(新增)

    返回总目录 本篇目录 介绍 安装 创建控制器 例子 样例项目 介绍 OData在其官网的定义是: 允许以一种 简单且标准的方式创建和使用可查询的.可互操作的RESTful APIs. 在ABP中也可以 ...

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

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

  6. ABP理论学习之Web API控制器(新增)

    返回总目录 本篇目录 介绍 AbpApiController基类 本地化 审计日志 授权 工作单元 其他 介绍 ABP通过Abp.Web.ApiNuget包集成了 ASP.NET Web API控制器 ...

  7. ABP理论学习之Javascript API(理论完结篇)

    返回总目录 本篇目录 Ajax Notification Message UI block和busy 事件总线 Logging 其他工具功能 说在前面的话 不知不觉,我们送走了2015,同时迎来了20 ...

  8. ABP理论学习之Swagger UI集成

    返回总目录 本篇目录 介绍 安装 安装Nuget包 配置 测试 介绍 从官方网站上可以看到:"启用了Swagger API,就可以获得交互式文档,生成和发现客户端SDK". 安装 ...

  9. ABP框架理论学习之Hangfire集成

    返回总目录 Hangfire是一个综合的后台工作管理者.你可以将Hangfire集成到ABP中,这样就可以不使用默认的后台工作管理者了.但你仍然可以为Hangfire使用相同的后台工作API.这样,你 ...

随机推荐

  1. C++预定义宏

    C/C++宏体中出现的#,#@,##: - #的功能是将其后面的宏参数进行字符串化操作(stringfication),就是对它所引用的宏变量通过替换后在其左右各加上一个双引号 -##被称为连接符(c ...

  2. NetMQ(二): 请求响应模式 Request-Reply

    ZeroMQ系列 之NetMQ 一:zeromq简介 二:NetMQ 请求响应模式 Request-Reply 三:NetMQ 发布订阅模式 Publisher-Subscriber 四:NetMQ ...

  3. vue-loader配合webpack的使用及安装

    vue-loader配合webpack的使用及安装: 工程文件简单的目录结构 index.html main.js   入口文件 App.vue   vue文件,官方推荐命名法 package.jso ...

  4. js 实现表格的可编辑状态

    实现表格的可编辑,点击修改以后可以编辑,代码如下: <!DOCTYPE HTML> <html> <head> <meta charset="utf ...

  5. 1、Spring In Action 4th笔记(1)

    Spring In Action 4th笔记(1) 2016-12-28 1.Spring是一个框架,致力于减轻JEE的开发,它有4个特点: 1.1 基于POJO(Plain Ordinary Jav ...

  6. xsl-mode属性用法

    本文出自 “熔 岩” 博客,出处http://lavasoft.blog.51cto.com/62575/60517 对某一个元素做多次处理,那么选择<xsl:apply-template元素处 ...

  7. C++-Qt【5】-QT的QString,char*,QByteArray转化以及中文乱码的问题

    引用:http://blog.sina.com.cn/s/blog_a7e2c7490101oatt.html QTextCodec *codec = QTextCodec::codecForName ...

  8. SQL注入攻防入门详解

    =============安全性篇目录============== 本文转载 毕业开始从事winfrm到今年转到 web ,在码农届已经足足混了快接近3年了,但是对安全方面的知识依旧薄弱,事实上是没机 ...

  9. SOAPUI使用教程-REST Service Mocking

    REST服务模拟 REST服务模拟功能允许您创建一个REST服务模拟器-MockService . 好处 RESTMockServices可用于例如: Web服务的原型 ——几秒内从请求生成一个完整的 ...

  10. [Leetcode] Number of Digit Ones

    Given an integer n, count the total number of digit 1 appearing in all non-negative integers less th ...