標籤:sha oninput cut 實體 表名 sof depends 介面 address
NHibernate整合
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整合