在DDD中,您的实体具有唯一的标识符(ID或UUID)。通常,一个实体代表数据库表中的一行。我的存储库可以一次加载一个实体(FindbyId)或所有实体(Findall)。
,但是现在必须用加入其他表格编写一个特殊且非常复杂的查询。结果集不再是一个特殊的(用户)实体,因为我从具有别名等多个表等的多个表中选择了不同的字段。根据查询,结果可能不包含ID。
我已经成功地将其水合成一个新的对象集合中,但是在那个东西的名称(和类型)中挣扎。
我的问题是:
如何从DDD中的自定义查询中命名和分类这样的行?
似乎您在这里需要查询服务。
DDD非常适合CQR,我相信您想要的结果是只读的。
在这种情况下,您为您的需求创建一个特殊的对象:用户data,如果用户包含一些其他关系(例如角色集合或正确),则可以称其为userrightsdata,并从userqueryseryservice中获取。p>查询服务通常在应用程序层中。
如果您想要一个不阅读的结果,而不是可以操纵和坚持的普通实体,则需要给我们更多详细信息。特别是,您应该能够从存储库加载该实体,调用域操作并通过应用程序服务坚持下去。
查询服务非常适合视图,表和数据显示,并带有排序,过滤等...
编辑:plalx在Eben Roux帖子的响应中钉了钉子。
ProjectName/
IdentityAndAccess/
Application/
Command/
AuthenticateUserCommand.php
ChangeEmailAddressCommand.php
ChangeUserPasswordCommand.php
ChangeUserPersonalNameCommand.php
...
Data/
UserData.php
UserRightsData.php (POPO containing User infos and a list of rights)
RightData.php (Single comment infos)
UserApplicationService.php
UserQueryService.php
Domain/
Model/
首先,除非您确实是在特定的聚集体之后,否则应避免查询域模型。即使那样,根据您的设计,您可能无法获取所需的数据。
典型的建议是使用专门的查询层以及代表所需数据的读取模型。该读取模型可能是您需要的键入或松动。例如,如果名称/值对列表可以完成问题,也许您可以选择。
这些查询实际上并不是域的一部分,因此,在建模方面,它们属于域驱动的设计。但是,它们作为您的整体体系结构/方法的一部分很重要。
更新:
回应@luca Masera的评论:
我通常使用类似的东西(c#),例如 Product
:
public interface IProductQuery
{
int ActiveCount();
DataRow Details(Guid id);
Query.Product Get(Guid id);
IEnumerable<Query.Product> Matching(ProductSpecification specification);
}
Query
命名间隙是这样,使读取模型Product
不会干扰我的实际域Product
。
根据我的要求,我将使用适当的返回对象/结构/类型。