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 application public 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集成