ABP领域层知识回看之—仓储

1. 前言

 在上一篇博文中 http://www.cnblogs.com/xiyin/p/6810350.html
我们讲到了ABP领域层的实体,那篇博文继续讲ABP的天地层,那篇博文的核心是ABP领域层—仓储。我们在上篇博文中牵线的ABP领域层的大体结构,在那篇小说就不一一赘述了。详情可以查看上篇博文。接下来直接进入正题。仓储的概念是那般的:

在天地层和多少映射层的中介,使用类似集合的接口来存取领域对象—-马丁Fowler。

仓储被用于领域对象在数据库上的操作(实体Entity和值对象
Value types),一般的话,大家本着差其余实体(或聚合根Aggregate Root
会成立相呼应的贮存。

疑问:“这是还是不是对每种实体都创设相应的存储呢?”

本文讲述的结构如下:

图片 1

接下去,作者将相继讲述。

贰零壹贰年阿拉伯埃及共和国(The Arab Republic of Egypt)骚乱

二〇一二年八月2十八日初阶,埃及(Egypt)全民由于不满物价上升、失去工作率高和败坏等难题,阿拉伯埃及共和国多个都市暴发民众广泛集会,需求总统Mubarak下台。本来那只是一场小范围的抗议运动,却如星火燎原般点燃了阿拉伯埃及共和国(The Arab Republic of Egypt)老百姓的设想,接下去4个月暴发的事,完全出人意料,中东野史最遥远、最有势力的独裁政权就这么分崩离析了,独裁者Mubarak被赶下台。四月30日Mubarak发表辞去,将权力移交给军方。

2.ABP领域层—仓储

公司的挑衅

美利坚合众国国家公共广播电视台(NP本田UR-V)派遣长时间担任战地记者和发行人的J·J·萨瑟兰到埃及(Egypt)报导当地气象。他到埃及(Egypt)的时候,机场现已关门,手机信号和互连网已经切断。他的办事是扶持协会尽只怕地展现出最好的电视公布,他无权命令旁人做任何事,而是尽量满足客人的渴求。管理层下达的一声令下是发表音讯报纸发布,而且一天要播报数十次,现场集体要做的就是找出应对那一个挑战的不二法门,并且决定要报纸公布哪些事以及哪些运用通讯手段公布出来。

2.1 IRepository 接口


 在ABP中,仓储类要落实IReposiotry接口。最好的情势是本着不一致仓储对象定义各自差距的接口。

如若你的实体IDint 类型的,那么可以选取如下概念:

public  interface IPersonREpository : IRepository<Person>
{
  //...
}

要是或不是int 类型的,可以动用如下概念:

public interface IPersonRepository : IRepository<Person, long>
  {
    //...
  }

对于仓储类,IRepository概念了过多泛型的点子。比如Insert,Select,Update,Delete,
详情能够在源码的Abp.Domain.Repositories 程序集中详细查看。

接下去对CRUD展开每种的介绍。

自管理团队

因为很难和华盛顿管理层联系上,一切都是他们依靠自身的力量已毕的。由于现场的意况白云苍狗,华盛顿的高层根本无法立马地一直提出引导,团队成员必须自行决定怎么着成功工作。管理层的天职在于制定战略目的,团队的干活则是决定如何形成目的。

2.1.1 查询(Query)


 *拿到单一实体:

TEntity Get(TPrimaryKey id);
Task<TEntity> GetAsync(TPrimaryKey id);
TEntity Single(Expression<Func<TEntity,bool>> predicate);
TEntity FirstOrDefault(TPrimaryKey id);
Task<TEntity> FirstOrDefaultAsync(TPrimaryKey id); TEntity FirstOrDefault(Expression<Func<TEntity, bool>> predicate); Task<TEntity> FirstOrDefaultAsync(Expression<Func<TEntity, bool>> predicate); TEntity Load(TPrimaryKey id)

Get艺术被用于依据主键值(Id)取得相应的实业。当数据库中依据主键值找不到相适合的实业时,它会抛出13分。

根本讲一下Single办法的实例,因为参数是八个表明式:

var person = _personRepository.Get(42);
var person = _personRepository.Single(p => p.Name == "Robert");

Tip1:Single形式在付给的尺度找不到实体或符合的实体当先2个之上时,都会抛出很是。

Tip2:FirstOrDefault也一致,然而当没有符合Lambda
表明式或Id的实业时,会回到null(取代抛出尤其)。当有超越三个上述的实业符合条件,它只会再次来到第1个实体。

Tip3: Load
并不会从数据库中摸索实体,但它会成立延迟履行所需的代理对象。假设您只使用Id
属性,实际上并不会招来实体,它唯有在你存取想要查询实体的某部属性时才会从数据库中询问实体。

*得到实体列表:

List<TEntity> GetAllList(); Task<List<TEntity>> GetAllListAsync(); List<TEntity> GetAllList(Expression<Func<TEntity, bool>> predicate); Task<List<TEntity>> GetAllListAsync(Expression<Func<TEntity, bool>> predicate); IQueryable<TEntity> GetAll();

GetAllList 被用于从数额中追寻全部实体,重载并且提供过滤实体的效果,

var allPeople = _personRepository.GetAllList();
var somePeople = _personRepository.GetAllList(person => person.IsActive && person.Age > 20 );

GetAll返回IQueryable<T>品类的目的。因为是IQueryable
类型的,所以大家可以在调用达成后,进行Linq操作。相关的Linq操作函数,可以查看自身的那篇博文。示例:

var query = from person in _personRepository.GetAll()
  where person.IsActive
  orderby person.Name
  select person;
var people = query.ToList();

List<Person> personList2 = _personRepository.GetAll().Where(p =>p.Name.Contains("H")).OrderBy(p => p.Name).Skip(40).Take(20).ToList();

*自定义再次来到值

ABP 有3个外加的不二法门来完毕IQueryable<T>
的推迟加载效果,而不需求在调用的办法上添加UnitOfWork本条性子卷标。

T Query<T> (Func<IQueryable<TEnity>,T> queryMethod);

询问艺术接受 Lambda(或三个措施)来经受IQueryabel<T>
并且再次来到任何对象类型。示例:

var person = _personRepository.Query(q => q.Name.Contains("H").OrderBy(p => p.Name).ToList());

引入Scrum

她俩采纳了Scrum方法,他们的到期期限须要她们无法不每11个钟头截五回稿。J·J·萨瑟兰都会向社团提议八个很简单的题材:1).从大家上次研商到前些天,你做了何等?2).在我们下次再议论此前,你打算做什么样?3).你境遇了哪些障碍?询问那几个难点是Scrum流程的定点环节,那足以促使记者们相互商量,互相分享音信。

其实,他扮演着“ScrumMaster”的角色。在历次开会后,他都要确保救助组织解决障碍。团队的障碍恐怕出自各样因素,比如:与埃及(Egypt)埃及(Egypt)官僚打交道、找到安全的公寓房间、寻找司机和翻译、支持记者摆脱埃及(Egypt)秘密警察的羁押等。

这一体是怎么形成的啊?伊始,他们陷入了一片混乱,相互之间争辨不断,不能迅速地成功情报广播职分,但快捷,他们就落到实处了无往不利的周转,根本不须求管理层的治本。相反,团队成员会管理好团结。在接下去的多少个星期内,派驻开罗的团体揭橥的音信电视揭橥数量领先全部人的预想,报纸公布的身分也当先了竞争对手,最终还荣获了多少个奖项。他们成功了。

现行,Scrum方法在美利坚合众国国度公共广播广播台内部拿到了广泛应用,

集团才是让这么些世界运营的根本力量,那也是Scrum赖以达成的基础。

2.1.2 新增


IRepository 接口定义了之类方法来新增壹个实体到数据库。

TEntity Insert(TEntity entity); Task<TEntity> InsertAsync(TEntity entity); TPrimaryKey InsertAndGetId(TEntity entity); Task<TPrimaryKey> InsertAndGetIdAsync(TEntity entity); TEntity InsertOrUpdate(TEntity entity); Task<TEntity> InsertOrUpdateAsync(TEntity entity); TPrimaryKey InsertOrUpdateAndGetId(TEntity entity); Task<TPrimaryKey> InsertOrUpdateAndGetIdAsync(TEntity entity);

**Tip:**
新增方法会新增实体到数据库并且再次来到相同的已新增实体。InsertAndGetId方法会重返新增实体的标识符(Id)。当我们运用电动递增标识符值且需求拿到实体的新暴发标志符值时非常好用。

快快革命

如上传说出自杰夫•萨瑟兰的《敏捷革命》
那本书。J·J·萨瑟兰
是杰夫•萨瑟兰的幼子,怪不得他当做记者懂Scrum,他四伯是“Scrum之父”。
图片 2

2.1.3 更新


TEntity Update(TEntity entity);
Task<TEntity> UpdateAsync(TEntity entity)

有关笔者

杰夫•萨瑟兰(JeffSutherland),Scrum发明者与一同创建人,被誉为“Scrum之父”,《敏捷宣言》起草人之一。

2.1.4 删除


void Delete(TEntity entity); 
Task DeleteAsync(TEntity entity); 
void Delete(TPrimaryKey id); 
Task DeleteAsync(TPrimaryKey id);
void Delete(Expression<Func<TEntity, bool>> predicate); 
Task DeleteAsync(Expression<Func<TEntity, bool>> predicate); 

2.1.5 其他形式


int  Count(); 
Task<int> CountAsync(); 
int  Count(Expression<Func<TEntity, bool>> predicate); 
Task<int> CountAsync(Expression<Func<TEntity, bool>> predicate); Long  LongCount(); 
Task<long> LongCountAsync(); 
Long  LongCount(Expression<Func<TEntity, bool>> predicate); Task<long> LongCountAsync(Expression<TEntity, bool>> predicate)

2.2 仓储的已毕


 ABP在统筹上是采取不指定ORM框架或其余存取数据库技术的方式。只要完毕IRepository接口,任何框架都可以使用。

 当你采用NHIbernate
EntiyFramework,假若提供的措施已充足使用,你就不须要为你的实业创造仓储对象了。大家得以直接流入IRepository<TEntiy>IRepository<TEntity,TPrimaryKey>
上面实例为application service选取仓储来新增实体到数据库:

public class PersonAppService : I PersonAppService
{
    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);
}

2.3 管理数据库连接


数据库连接的敞开和关闭,在仓储方法中,ABP会自动化的开展连接管理。

 当仓储方法被调用后,数据库连接会自动开启且运营工作。当仓储方法执行完成并且再次回到现在,全部的实业变化都会被储存,事务被交付并且数据库连接被关闭,一切都由ABP自动化的控制。如若存储方法抛出任何类型的格外,事务会自动地回滚并且数据连接会被关闭。

 若是存储方法调用其他仓储方法(尽管是见仁见智的存储的措施),它们共享同八个老是和事务。连接会由仓储方法调用链最上层的非凡仓储方法所管理。

2.4 仓储的生命周期


 全部的储存对象都以暂时性的,那就是说,它们是在由索要的时候才会被成立。ABP大批量的应用保护注入,当仓储类必要被注入的时候,新的类实体会由注入容器自动地创造。

2.5 仓储的特等实践


  • 对此3个T类型的实业,是足以利用IRepository<T>
    。但别任何情况下都创造定制化的储存,除非大家确实很需求。预约于储存方法已经充足应付各样案例。
  • 创制定制的存储可以落成IRepository<TEntity>
  • 积存类应该是无状态的。那意味着,你不应该定义仓储等级的情事对象并且仓储方法的调用也不该影响到其余调用。
  • 当仓储可以选用像 正视注入,尽恐怕较少,或不依照其余服务。

3. 结语

 正好让本人想起回想之前阅读的书。虽说都是基础内容,但也加重了其知晓,下一篇将会讲
工作单元。听大人说是最看好的。。哈哈。

4.参考文献

Post Author: admin

发表评论

电子邮件地址不会被公开。 必填项已用*标注