本篇目录
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集成的更多相关文章
-
ABP理论学习之SignalR集成
返回总目录 本篇目录 介绍 安装 建立连接 内置功能 你自己的SignaR代码 介绍 Abp.Web.SignalR 使得在基于ABP的应用程序中使用 SignalR相当容易.查看SignalR文档获 ...
-
ABP理论学习之EntityFramework集成
返回总目录 本篇目录 Nuget包 创建DbContext 仓储 仓储基类 实现仓储 自定义仓储方法 阅读其他 ABP可以使用任何ORM框架工作,并且已经内置了EntityFramework集成.这篇 ...
-
ABP理论学习之OWIN集成
返回总目录 如果你的应用中使用了OWIN,那么需要在主项目(一般来说是指Web项目)中添加Abp.Owin的nuget包,然后像下面那样在OWIN的 Startup文件中调用 UseAbp()扩展方法 ...
-
ABP理论学习之OData集成(新增)
返回总目录 本篇目录 介绍 安装 创建控制器 例子 样例项目 介绍 OData在其官网的定义是: 允许以一种 简单且标准的方式创建和使用可查询的.可互操作的RESTful APIs. 在ABP中也可以 ...
-
ABP官方文档翻译 9.3 NHibernate集成
NHibernate集成 Nuget包 配置 实体映射 仓储 默认实现 自定义仓储 应用程序特定基础仓储类 ABP可以使用任何ORM框架,它内置集成NHibernate.此文档将讲解ABP如何使用NH ...
-
ABP理论学习之Web API控制器(新增)
返回总目录 本篇目录 介绍 AbpApiController基类 本地化 审计日志 授权 工作单元 其他 介绍 ABP通过Abp.Web.ApiNuget包集成了 ASP.NET Web API控制器 ...
-
ABP理论学习之Javascript API(理论完结篇)
返回总目录 本篇目录 Ajax Notification Message UI block和busy 事件总线 Logging 其他工具功能 说在前面的话 不知不觉,我们送走了2015,同时迎来了20 ...
-
ABP理论学习之Swagger UI集成
返回总目录 本篇目录 介绍 安装 安装Nuget包 配置 测试 介绍 从官方网站上可以看到:"启用了Swagger API,就可以获得交互式文档,生成和发现客户端SDK". 安装 ...
-
ABP框架理论学习之Hangfire集成
返回总目录 Hangfire是一个综合的后台工作管理者.你可以将Hangfire集成到ABP中,这样就可以不使用默认的后台工作管理者了.但你仍然可以为Hangfire使用相同的后台工作API.这样,你 ...
随机推荐
-
python学习--字符串
python的字符串类型为str 定义字符串可以用 ‘abc' , "abc", '''abc''' 查看str的帮助 在python提示符里 help(str) python基于 ...
-
从下往上看--新皮层资料的读后感 第四部分 来自神经元的设计-perceptron 感知机
搬地方了,其他的部分看知乎:https://zhuanlan.zhihu.com/p/22114481 直到50年代,perceptron被Frank Rosenblatt搞了出来.perceptro ...
-
aehyok.com的成长之路二——技术选型
前言 首先奉上个人网站地址传送门:aehyok.com 在上一篇博客中http://www.cnblogs.com/aehyok/p/3934197.html主要简单的介绍了自己做个人网站的初衷, ...
-
.net常見面試題(二)
一.选择题 1. 下面叙述正确的是___C___. A.算法的执行效率与数据的存储结构无关 B.算法的空间复杂度是指算法程序中指令(或语句)的条数 C.算法的有穷性是指算法必须能在执行有限个步骤之后终 ...
-
hive的安装和升级
目录 [toc] 安装 升级 安装 nohup hive –service hiveserver & 启动: sudo nohup ./hive --service metastore &am ...
-
“纽劢科技杯”第十六届同济大学程序设计竞赛暨上海邀请赛同步赛 J-张老师的游戏
传送门 题目描述 在空闲时间,张老师习惯性地和菜哭武玩起了取石子游戏,这次的游戏规则有些不同,在他们面前有n堆石子,其中,第i堆石子的个数为a[i],现在制定规则如下: 从张老师开始, ...
-
在Vue中使用样式
##使用class样式 一共四种方式在注释中有解释 <!DOCTYPE html> <html> <head> <meta charset="utf ...
-
自定义数据类型 typedef
其实就是为数据类型起一个别名. typedef unsigned char AGE; //字符类型AGE x; //等价于 unsigned char x; typedef int * IPointe ...
-
Failure [INSTALL_CANCELED_BY_USER]
安装app到真机,遇到 Failure [INSTALL_CANCELED_BY_USER] 错误. 解决方法:将手机的USB安装权限打开即可.设置->更多设置->开发者选项->US ...
-
Android 基础题目
1. BroadcastReceiver 在UI thread? BroadcastReceiver 总是在UI thread, If you register your BroadcastRecei ...