在ABP框架域层解析实体类和存储类

在ABP框架域层解析实体类和存储类
领域层

实体是领域驱动设计的核心概念之一,Eric Evans就是这样描述的。许多对象不是由它们的属性定义的,而是由一系列连续事件和标识设计的。

译者注:对象不是其属性的基本定义,但应该由其线性连续性和恒等式来定义,因此,实体是具有唯一标识的ID,并存储在数据库中。实体通常映射到数据库中的表中。

实体类(实体类)

在ABP中,实体从实体类继承,见下面的例子:
公共类人员:实体
{
公共虚拟字符串名称{;get;set;}

公共虚拟时间创作时间{有};集;

公共任务()
{
创作时间=现在的日期时间;
}
}

Id类被定义为一个实体,它有两个属性,它的父元素有一个id属性。id是这个实体的主键。因此,从实体类继承所有实体的主键(所有实体的主键都是id字段)。

可以更改id(主键)数据类型默认值是int类型。如果要定义其他类型的ID,则应声明id的类型如下示例。
公共类人员:实体
{
公共虚拟字符串名称{;get;set;}

公共虚拟时间创作时间{有};集;

公共任务()
{
创作时间=现在的日期时间;
}
}

可以将其设置为字符串、GUID或其他数据类型。

实体类重写等式(= =)运算符是用来确定两个对象是否相等(两单位等于ID),大都是瞬时性()方法检测是否还定义一个实体一个ID属性。

界面公约

在许多应用中,许多实体属性(数据库表的创建时间也有场)表示当实体是created.apb提供了一些有用的接口实现类似的功能。也就是说,一个普遍的编码方法是为那些实体实现这些接口。

(1)审计(审计)

实体类实现的创作时间性能的ihascreationtime接口。当实体插入到数据库中,ABP自动设置为当前时间的属性值。
ihascreationtime公共接口
{
在创作时间{得到;集;}
}
人类可以改写为下面的示例实现ihascreationtime接口:
人类:实体,IHasCreationTime
{
公共虚拟字符串名称{;get;set;}

公共虚拟时间创作时间{有};集;

公共任务()
{
创作时间=现在的日期时间;
}
}

icreationaudited从ihascreationtime和接口有一个属性CreatorUserId:
公共接口icreationaudited:ihascreationtime
{
长creatoruserid {有};集;
}
当一个新的实体保存,ABP自动设置CreatorUserId的值为当前用户的ID

你可以很容易地实现icreationaudited接口。通过导出实体类creationauditedentity(因为该类实现了icreationaudited界面,我们可以直接继承creationauditedentity类来实现上述功能),它有一个通用的版本,实现不同的ID数据类型(默认为int),它可以给不同的数据类型ID(ID的实体类)。

下面是实现类似修改功能的接口
imodificationaudited公共接口
{
日期时间lastmodificationtime {得到;集;}
长lastmodifieruserid {有};集;
}
当一个实体更新时,ABP会自动设置这些属性的值。

如果你想实现所有审计的属性,您可以扩展iaudited接口直接;的例子如下:
公共接口iaudited:icreationaudited,imodificationaudited
{

}
作为一个快速发展的模式,你可以直接从auditedentity类,不需要实现的iaudited接口(的auditedentity类所实现的功能,该类直接继承可以实现上述功能,auditedentity)的类有一个不同的ID数据类型的泛型版本(默认是int),可以ID(实体类ID)不同的数据类型。

(2)软删除(软删除)

软的缺失是一种常见的方式,是用来标志一个实体,已被删除,而不是从数据库上删除记录。例如,你可能不想努力从数据库中删除用户记录,因为它与许多其他的表相关联。实现软删除的目的,我们可以实现接口isoftdelete:
isoftdelete公共接口{
布尔isDeleted {有};集;
}
ABP实现了打开框的软删除模式,当删除软删除的实体被删除时,ABP会感知操作并防止它被删除。设置isDeleted属性值为true,更新数据库中的实体,也就是说,软删除记录不能从数据库中检索,和ABP自动过滤器为我们软删除记录。(例如:选择查询,即查询的查询分析器在ABP,没有数据库。)

如果你使用软删除,你也可以实现此功能,这是记录谁删除实体。实现此功能可以实现ideletionaudited接口。请看下面的例子:
公共接口ideletionaudited:isoftdelete
{
长deleteruserid {有};集;
日期时间deletiontime {得到;集;}
}
正如你看到的,ideletionaudited从isoftdelete interface.abp自动设置这些属性的值时,一个实体被删除。

如果你想将所有的审计接口的实体,例如,创造(创作),修改(修改)和删除(删除),你可以直接实现ifullaudited接口,因为接口继承这些接口。
公共接口ifullaudited:iaudited,ideletionaudited
{

}
作为一种快捷方式,可以直接从fullauditedentity类派生出你的实体类,因为阶级已经实现了ifullaudited接口。

注:审计接口和类都有一个通用的导航属性自定义您的用户实体模板(例如icreationaudited和FullAuditedEntity),在TUser创建,修改和删除用户类型的实体类,在源代码详细看(abp.domain.entities.auditing空间fullauditedentity)。TprimaryKey是唯一ID的基类型,默认为int。

(3)激活状态/空闲状态(主动/被动)

一些实体需要被标记为活动或空闲。然后你可以为实体采取主动/被动状态的行动。基于这个原因产生的实体,可以延长ipassivable接口来实现这个功能,接口定义的活跃性。

如果你创造了首次实体标记为激活状态,可以设置真实的活跃属性值的构造函数

这是不同于软删除(isDeleted)。如果实体是软删除,无法从数据库中检索(有过滤软删除记录),但激活或闲置的实体,你是完全取决于你如何得到这些标记的实体。

认同接口

事实上,实体实现认同接口(和认同的接口来实现与实体)。如果你不想从实体类,你可以实现这些接口直接。其他单位也可以实现相应的接口,但不推荐你使用这个,除非你有没有从实体类的一个很好的理由。
仓库(仓库)

仓库定义:域层和数据映射层的中介使用类似的接口集合访问域对象(Martin Fowler)。

事实上,仓库用于在数据库上操作域对象(实体实体和值对象值类型),一般来说,我们为不同的实体(或聚合根聚合根)创建相应的仓库。

IRepository接口

在ABP,库类实现IRepository接口。最好的办法是定义不同的仓库对象不同的接口。

实体实体的仓库接口声明的示例如下所示:
公共ipersonrepository IRepository界面:
{
}
ipersonrepository继承自IRepository,它是用来定义ID就是int类型的实体(Int32)。如果你的实体ID数据类型是int,你可以继承IRepository界面,如下图所示:
公共ipersonrepository IRepository界面:
{
}
仓储类IRepository定义了一系列通用的方法。例如,选择,插入,更新,删除方法(CRUD操作)。大多数时候,这些方法已经满足了一般实体的需求。如果这些党派足够的实体,我们不需要创建存储接口 /类实体的需求。在执行部分的更多细节。

(1)查询(查询)

IRepository的定义从数据库中检索实体的常用方法。

获取单个实体(获取单个实体):

tentity得到(tprimarykey ID);
任务GetAsync(tprimarykey ID);
TEntity Single(表达式>谓语);
TEntity FirstOrDefault(tprimarykey ID);
任务firstordefaultasync(tprimarykey ID);
TEntity FirstOrDefault(表达式>谓语);
任务firstordefaultasync(表达式>谓语);
TEntity Load(tprimarykey ID);
获取的方法是使用基于主键值获得相应的实体(ID)。当数据库中找不到一个一致的实体根据主键值是一个例外。单方法类似于get方法,但它的输入参数是一个表达式,而不是一个主键值(ID)。所以,我们可以写lambda表达式得到实体的例子如下:
无功的人= _personrepository.get(42);
无功的人= _personrepository.single(P = O的名字= =Halil易卜拉欣该);
注意,当给定条件找不到实体或多个实体时,单个方法抛出异常。

FirstOrDefault是相同的,但在没有实体,符合一个lambda表达式或ID,它将返回null(而不是抛出异常)。当多个实体,符合条件的,它只会返回第一实体。

加载不会从数据库中检索实体,但它会创建延迟执行所需的代理对象。它只会从数据库中查询实体你访问一些属性的实体,你想查询的时候,当有一个性能要求,这种方法可以用来代替GET方法。加载方法也是NHibernate和ABP的实现。如果ORM提供者(Provider)没有实现这种方法,加载方法运行相同的获得方法。

ABP的一些方法有异步(异步)的版本,可以应用于异步开发模式(见异步方法的相关部分)。

B,实体列表(获取实体列表):
getalllist(名单);
任务> getalllistasync();
表getalllist(表达式>谓语);
任务> getalllistasync(表达式>谓语);
IQueryable GetAll();
getalllist用于从数据库检索的所有实体。它是重载的,提供过滤实体的功能,如下:
无功的人= _personrespository.getalllist();
VaR的人= _personrepository.getalllist(人= > person.isactive人。年龄> 42);
获得返回类型IQueryable对象。所以我们可以调用此方法后做LINQ操作的例子:


VaR查询=从人_personrepository.getall()
在person.isactive
人的名字进行排序
选择的人;
无功的人= query.tolist();
例二
表personlist2(,)= _personrepository.getall(P = p.name.contains(H))。OrderBy(P =器)和跳跃(40),(20)(。列出);

如果getAll方法被调用,那么几乎所有的查询可以使用LINQ。它甚至可以用来编写连接表达式。

说明:关于IQueryable

当你调用外部的库对象的获得方法,你必须打开数据库连接。这是因为IQueryable允许延迟执行,将执行数据库查询,直到您调用ToList方法或使用IQueryable在foreach循环(或访问查询对象的方法)。因此,当你打电话的列出的方法,数据库的连接必须启用。我们可以使用提供的ABP是UnitOfWork调用的方法实现的功能。注意应用程序服务的方法假定UnitOfWork。因此,在获得方法的使用不需要的功能除了UnitOfWork作为一种应用服务的方法。

有些方法有异步版本可以应用于异步开发模式(见异步方法的章)。

自定义返回值(自定义返回值)

ABP的延迟加载效果也达到了IQueryable的另一种方法,而不需要在调用方法添加UnitOfWork属性标签。
T查询(函数,T>querymethod);
查询方法接受λ(或方法)得到IQueryable和返回任何对象类型的实例如下:

无功的人= _personrepository.query(Q =在哪里(P = p.name.contains(H)(P.OrderBy)= >(器)。列出));

因为lambda(或方法)是在仓库对象的方法中执行的,所以只有在数据库连接打开之后才执行它。

(2)新(插入)

的IRepository接口定义了一个简单的方法来对数据库提供了一个新的实体:
TEntity Insert(tentity实体);
任务insertasync(tentity实体);
TPrimaryKey InsertAndGetId(tentity实体);
任务insertandgetidasync(tentity实体);
TEntity InsertOrUpdate(tentity实体);
任务insertorupdateasync(tentity实体);
TPrimaryKey InsertOrUpdateAndGetId(tentity实体);
任务insertorupdateandgetidasync(tentity实体);
新方法将实体到数据库并返回相同的新增实体,insertandgetid方法返回的标识符(ID)的新的实体。它很好,当我们使用自动增加标识符值和需要新生成的标识符的entity.insertofupdate值将添加或更新实体,和选择取决于Id是否有价值。最后,insertorupdatedandgetid返回ID值实体后添加或更新。

所有的方法都有异步版本,可以应用到异步开发模型(见异步方法部分)。

(3)更新(更新)

IRepository定义了一个方法来更新已经在数据库中的一个实体,它更新的实体和返回相同的实体对象。
tentity更新(tentity实体);
任务updateasync(tentity实体);
(4)删除(删除)

IRepository已经制定了一些方法来删除现有数据库中的实体。
删除(tentity实体);
任务deleteasync(tentity实体);
删除(tprimarykey ID);
任务deleteasync(tprimarykey ID);
删除(表达式>谓词);
任务deleteasync(表达式>谓语);
第一种方法接受现有实体,第二种方法接受现有实体的ID。

最后一个方法接受一个条件来删除一个符合的实体。请注意,所有符合谓词表达式的实体将首先被检索,然后被删除。因此,使用非常小心,如果有太多的实体满足条件,就可能造成许多问题。

所有的方法都适用于异步开发模式的异步版本(见异步方法的章)。

(5)其他方法(其他)

IRepository也提供了大量的获取数据表中单位数的方法。

Int Count();
任务countasync();
Int Count(表达式>谓词);
任务countasync(表达式>谓语);
Long LongCount();
任务longcountasync();
长longcount(表达式>谓语);
任务longcountasync(表达式>谓语);
所有的方法都用在异步开发模式的异步版本(见异步方法的章)。

(6)对异步方法(关于异步方法)

ABP支持异步开发模式。因此,仓储的方法有异步版本。下面是一个例子,应用服务的方法,采用异步模型:

公共课personappservice:AbpWpfDemoAppServiceBase,IPersonAppService
{
私人只读IRepository _personrepository;

公共personappservice(IRepository personrepository)
{
_personrepository = personrepository;
}

公共异步任务getAllPeople()
{
无功的人=等待_personrepository.getalllistasync();

返回新的getpeopleoutput
{
人=地图绘制者(人)
};
}
}

getAllPeople方法是异步的,使用getalllistasync等待保留关键字。

如果不是在每一个ORM框架提供。

这是从EF提供异步能力。如果ORM框架没有提供异步存储方法,它将在一个同步的方式。同样的,例如,对insertasync手术如EF加一样,因为EF将写新的主体数据库(DbContext。调用SaveChanges)直到单元操作完成(工作单位)。

存储的实现

公司是在不指定一个特定的ORM框架或其他数据库访问技术设计。任何框架可以用只要IRepository接口的实现。

仓储是容易使用NHibernate或有效实施。

EntityFramework

当你使用NHibernate或者EntityFramework,你不需要如果方法可创建您的实体仓库对象。我们可以把IRepository(或IRepository)直接。下面的例子使用添加实体数据库应用服务仓库对象:
公共课personappservice:ipersonappservice
{
私人只读IRepository _personrepository;

公共personappservice(IRepository personrepository)
{
_personrepository = personrepository;
}

公共无效CreatePerson(CreatePersonInput输入)
{
人=人= {名称输入名称,地址=输入电子邮件地址};

_personrepository.insert(人);
}
}
对personappservice构造函数注入IRepository和使用插入的方法。当你需要创建一个定制的仓储实体的方法,你应该创建一个存储库类指定的实体。

管理数据库连接

数据库连接被打开和关闭,在仓库方法中,ABP将自动连接管理。

当调用存储方法时,数据库连接将自动打开并启动事务。当执行和返回仓库方法时,将存储所有实体更改,将提交事务,并关闭数据库连接。一切都是由总部自动化控制。如果仓储方法抛出任何类型的异常,事务将自动回滚,数据连接是关闭的,以上所有操作都可以在所有实现IRepository接口库类开放调用的方法。

如果存储方法调用其他库存的方法(即使是在不同的仓储方法),它们共享相同的连接和交易。连接是由仓库的方法是存储方法调用链的上层管理。更多关于数据库管理,看到UnitOfWork文件

存储的生命周期

所有仓储的对象是临时性的。也就是说,他们创造了当他们在need.abp大量使用依赖注入,当库类需要注入,新课现实是由注入容器自动创建。基于注入文件查看更多信息。

仓储的最佳做法

对于类型T的一个实体,它可以使用IRepository的。但不在任何情况下,创建定制的仓库,除非我们真的需要它。预定义的仓储方法足以应对各种情况。

如果你创建一个定制的仓库(IRepository)

存储类应该是无状态的,这意味着你不应该定义仓库水平状态对象,仓库的方法调用不应该影响其他电话。 U3000 U3000 U3000 U3000

当存储可根据注射使用,很少或没有根据其他服务。 U3000
免责声明:本网信息来自于互联网,目的在于传递更多信息,并不代表本网赞同其观点。其原创性以及文中陈述文字和内容未经本站证实,对本文以及其中全部或者部分内容、文字的真实性、完整性、及时性本站不作任何保证或承诺,并请自行核实相关内容。本站不承担此类作品侵权行为的直接责任及连带责任。如若本网有任何内容侵犯您的权益,请及时联系我们,本站将会在24小时内处理完毕。
相关文章
返回顶部