Model view controller 什么';查询DTO投影的正确位置是哪里?
出于不同的原因(关注点分离、性能),我希望停止向视图发送域实体,而是使用DTO投影 我想使用ORM查询来创建DTO,只从一个或多个实体中选择所需的字段 正确的地点是哪里?Model view controller 什么';查询DTO投影的正确位置是哪里?,model-view-controller,domain-driven-design,dto,Model View Controller,Domain Driven Design,Dto,出于不同的原因(关注点分离、性能),我希望停止向视图发送域实体,而是使用DTO投影 我想使用ORM查询来创建DTO,只从一个或多个实体中选择所需的字段 正确的地点是哪里? 答:没有 控制器:我希望使它们尽可能薄,并避免让它们执行查询和/或映射 我觉得应该有一个集中的地方(类似于实体的存储库)来查询和创建DTO,但我没有找到这种做法的模式或命名 我遇到过这个术语,但它看起来像是用于将一个或多个域实体映射到DTO,而在我的例子中,我希望跳过加载完整实体,直接将数据库查询转换为DTO 这有一种模式
- 答:没有
- 控制器:我希望使它们尽可能薄,并避免让它们执行查询和/或映射
I{Aggregate}查询
,使用方式与使用I{Aggregate}存储库
相同
接口将以尽可能简单的格式返回数据:
namespace Company.Project.DataAccess
{
public interface ICustomerQuery
{
int CountMatching(Query.Customer.Specification specification);
int Count();
IEnumerable<DataRow> RowsMatching(Query.Customer.Specification specification); // perhaps OK for simple cases
IEnumerable<Query.Customer> Matching(Query.Customer.Specification specification); // for something more complex
}
}
您的DTO代表一个读取模型。为此,我通常使用一个查询“层”(尽管我倾向于更多地考虑关注点而不是层)。我通常使用I{Aggregate}查询
,使用方式与使用I{Aggregate}存储库
相同
接口将以尽可能简单的格式返回数据:
namespace Company.Project.DataAccess
{
public interface ICustomerQuery
{
int CountMatching(Query.Customer.Specification specification);
int Count();
IEnumerable<DataRow> RowsMatching(Query.Customer.Specification specification); // perhaps OK for simple cases
IEnumerable<Query.Customer> Matching(Query.Customer.Specification specification); // for something more complex
}
}
dto是应用层的对象。您想要的是直接从数据库填充它。它是cqrs的查询端,您没有像命令端那样的丰富域模型,只有适合客户端的投影(dto)。它们是查询(读取)模型 更新: 这些是我使用的模式的对象,类似于命令,但查询有一个结果:
public interface QueryResult {}
普通DTO(或它们的列表),带有客户端的输出数据
public interface Query<QR extends QueryResult> {}
公共接口查询{}
带有输入数据(搜索条件)的普通DTO,用于执行查询
public interface QueryHandler <QR extends QueryResult, Q extends Query<QR>> {
public QR handle ( Q query );
}
公共接口查询处理器{
公共QR句柄(Q查询);
}
执行查询的对象
public interface QueryHandler <QR extends QueryResult, Q extends Query<QR>> {
public QR handle ( Q query );
}
示例:
- 管理公司员工、部门等数据的应用程序
- 用例:给我一份30岁以下、工资超过2000欧元的员工名单(仅包括姓名、电子邮件、离职、工资)
class EmployeeDto{
私有字符串名称;
私人字符串电子邮件;
私有字符串departmentName;
私人双薪;
...
...
}
类EmployeeDtoList实现QueryResult{
私人名单雇员人数;
...
...
}
类EmployeesBageAndSalary实现查询{
私人日历最大年龄;
私人双敏沙拉;
...
...
}
类EmployeesBageAndSalaryHandler实现QueryHandler{
...
@凌驾
公共EmployeeDtoList句柄(EmployeesBageAndAlary查询){
...
...
}
}
--
客户端使用的facade是一个中介(与此方法的接口):
公共QR执行(Q查询);
中介器将由管理查询处理程序注册表的类实现,以便它将请求重定向到与给定查询关联的查询处理程序
它类似于命令模式,但带有查询。dto是应用层的对象。您想要的是直接从数据库填充它。它是cqrs的查询端,您没有像命令端那样的丰富域模型,只有适合客户端的投影(dto)。它们是查询(读取)模型 更新: 这些是我使用的模式的对象,类似于命令,但查询有一个结果:
public interface QueryResult {}
普通DTO(或它们的列表),带有客户端的输出数据
public interface Query<QR extends QueryResult> {}
公共接口查询{}
带有输入数据(搜索条件)的普通DTO,用于执行查询
public interface QueryHandler <QR extends QueryResult, Q extends Query<QR>> {
public QR handle ( Q query );
}
公共接口查询处理器{
公共QR句柄(Q查询);
}
执行查询的对象
public interface QueryHandler <QR extends QueryResult, Q extends Query<QR>> {
public QR handle ( Q query );
}
示例:
- 管理公司员工、部门等数据的应用程序
- 用例:给我一份30岁以下、工资超过2000欧元的员工名单(仅包括姓名、电子邮件、离职、工资)
class EmployeeDto{
私有字符串名称;
私人字符串电子邮件;
私有字符串departmentName;
私人双薪;
...
...
}
类EmployeeDtoList实现QueryResult{
私人名单雇员人数;
...
...
}
类EmployeesBageAndSalary实现查询{
私人日历最大年龄;
私人双敏沙拉;
...
...
}
类EmployeesBageAndSalaryHandler实现QueryHandler{
...
@凌驾
公共EmployeeDtoList句柄(EmployeesBageAndAlary查询){
...
...
}
}
--
客户端使用的facade是一个中介(与此方法的接口):
公共QR执行(Q查询);
中介器将由管理查询处理程序注册表的类实现,以便它将请求重定向到与给定查询关联的查询处理程序
它类似于命令模式,但有查询。这是一个很好的问题 您可以将它们放在应用程序层中。您寻找的模式称为查询服务 看看Vaughn Vernon(实现域驱动设计的作者)在其github repo中的表现: 然后,他直接从查询服务(CQRS)中的DB填充它们