1. 程式人生 > >ABP官方文檔翻譯 9.3 NHibernate集成

ABP官方文檔翻譯 9.3 NHibernate集成

mda sin 倉儲 pan 其他 獲取數據 get dso 映射類

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