首页 > 代码库 > ABP官方文档翻译 9.3 NHibernate集成
ABP官方文档翻译 9.3 NHibernate集成
NHibernate集成
- Nuget包
- 配置
- 实体映射
- 仓储
- 默认实现
- 自定义仓储
- 应用程序特定基础仓储类
ABP可以使用任何ORM框架,它内置集成NHibernate。此文档将讲解ABP如何使用NHibernate,假定你对NHibernate已经有了一定的了解。
Nuget包
在ABP中实现NHibernate做为ORM框架的Nuget包为Abp.NHibernate。你需要在应用程序中添加它。最好在一个单独的程序集中实现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()); }}
AbpNHibernateModule模块为使用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<T>的类,它自动映射Id属性并在构造函数中获取表名。所以,我从它继承并使用FluentNHibernate映射其他属性。当然,你可以直接从ClassMap继承,这样就可以使用FluentNHibernate的所有API和NHibernate的其他映射技术(如映射XML文件)。
仓储
仓储用于从高层抽象数据访问。参见仓储文档了解更多。
默认实现
在应用程序中,Abp.NHibernate包为实体实现了默认仓储。所以你不需要为实体创建仓储类就可以使用预定义的仓储方法。示例:
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>)并使用预定义的方法。参见仓储文档了解所有的预定义方法。
自定义仓储
如果你想添加一些自定义方法,首先需要添加一个仓储接口(作为最佳实践),然后在一个仓储类中实现它。ABP提供了一个基础类NhRepositoryBase来简单的实现仓储。为了实现IRepository接口,你的仓储类可以仅从这个类继承。
假定我们有一个Task实体,它可以分配给一个Person(实体)并且Task有一个State(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<Task>,然后我们可以使用给定的参数添加一些Where过滤器。最终,我们调用ToList()方法来获取任务列表。
你可以在仓储方法中使用Session对象来使用NHibernate的所有API。
注意:对于分层应用,在domain/core层定义自定义仓储接口,在NHibernate工程中实现它。这样,你就可以在任何工程中注入这个接口而不用引用NH。
应用程序特定基础仓储类
尽管你可以从ABP的NhRepositoryBase类继承你的仓储,但是创建自己的基础类并扩展NhRepositoryBase才是最佳实践。这样,你就可以轻松的在自己的仓储中添加shared/common方法。示例:
//Base class for all repositories in my applicationpublic abstract class MyRepositoryBase<TEntity, TPrimaryKey> : NhRepositoryBase<TEntity, TPrimaryKey> where TEntity : class, IEntity<TPrimaryKey>{ protected MyRepositoryBase(ISessionProvider sessionProvider) : base(sessionProvider) { } //add common methods for all repositories}//A shortcut for entities those have integer Id.public abstract class MyRepositoryBase<TEntity> : MyRepositoryBase<TEntity, int> where TEntity : class, IEntity<int>{ protected MyRepositoryBase(ISessionProvider sessionProvider) : base(sessionProvider) { } //do not add any method here, add the class above (since this inherits it)}public class TaskRepository : MyRepositoryBase<Task>, ITaskRepository{ public TaskRepository(ISessionProvider sessionProvider) : base(sessionProvider) { } //Specific methods for task repository}
返回主目录
ABP官方文档翻译 9.3 NHibernate集成