zoukankan      html  css  js  c++  java
  • ABP官方文档翻译 9.3 NHibernate集成

    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 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
    }

    返回主目录

  • 相关阅读:
    scrapy框架(一)
    selenium爬取京东商品信息
    自动化测试工具selenium的使用
    xpath选择器的使用
    爬取网页数据实例
    爬虫实操
    爬虫之`beautifulsoup4`模块
    DNS学习笔记
    MongoDB集群部署
    MongoDB单机部署
  • 原文地址:https://www.cnblogs.com/xajh/p/7158132.html
Copyright © 2011-2022 走看看