从表中查询数据时管理实体的最佳实践?
Best practices to manage entities while querying the data out of tables?
我数据库中的每个 table 都有自己的 POCO
class。现在,我已经开始编写复杂的 SQL 连接,查询结果集应该映射到某个实体,该实体可以发送到业务管理器(另一层)进行进一步处理。例如,想象一下我的查询 returns 列是这样的(table 名称以列名称为前缀为简单起见):
Customer.CustomerId,
Customer.CustomerName,
Customer.CustomerAddress,
[User].UserId,
[User].UserName,
[User].FirstName,
[User].LastName,
UserRole.RoleId,
UserRole.RoleName,
Employee.EmployeeId,
Employee.EmployeeName,
Employee.JoinDate,
MAX(AuditTrail.LastLoginDate)
etc
问题:
- 我应该使用什么设计模式?
- 我应该能够编写多个查询,并在每个查询中检索到一堆混合和匹配列。也许,不是一个
将这种类型的结果集映射到 POCO 是个好主意 classes?
- 我可能有其他查询,这些查询或多或少需要与 SQL 结果集中的 return 相同类型的列。
- 我是否应该维护单独的实体来支持查询?
注意:我正在使用 Dapper ORM 与带有 .NET 4.5 Framework (C#) 的 SQL Server 2012 通信。 如果问题不清楚,请告知。
1) Repository和Unit of work模式适用于处理数据库CRUD操作。
2 + 4) DTO 和 POCO 基本上是一回事。其中 DTO 通常是用于存储数据的 POCO。使用它们是一种很好的做法,因为这样您就始终知道要使用的对象中有什么。如果您根据业务需求而不是数据库需求构建 DTO,那么在大多数情况下您根本不需要更改它
3) 问题是什么?
P.S。
关于在 .Net 环境中使用 SQL,我建议使用不太新的 SSDT 数据库项目。它将帮助您跟踪您的模式
您要找的模式是Data Mapper
A layer of Mappers (473) that moves data between objects and a database while keeping them independent of each other and the mapper itself.
这意味着持久层之外的东西不应该知道关于数据库的任何信息——ORM 框架和模仿 table 结构的 POCO 都不应该知道。
因此,在 DDD 的上下文中,这意味着您使用域模型并将 DB POCO 映射到该域模型。数据映射器负责该映射。
实施
您当然可以自己进行映射:在数据映射器中创建一个方法,该方法采用 DB POCO 和 returns 相应的域对象。但是,如果您有很多映射,则这需要大量样板代码。
为了缓解这种情况,请使用像 AutoMapper 这样的对象到对象映射库。它减少了您为映射编写的代码量,还使映射更易于维护。缺点是你必须学习一个新的库并依赖它。
DB POCO 管理
您的 DB POCO(许多人称为 DTO)应仅服务于一个目的:描述 table 的结构或 C# 世界中的结果集 - 仅此而已。所以是的,为每个查询创建一个 DB POCO returns 不同的结果结构。
我数据库中的每个 table 都有自己的 POCO
class。现在,我已经开始编写复杂的 SQL 连接,查询结果集应该映射到某个实体,该实体可以发送到业务管理器(另一层)进行进一步处理。例如,想象一下我的查询 returns 列是这样的(table 名称以列名称为前缀为简单起见):
Customer.CustomerId,
Customer.CustomerName,
Customer.CustomerAddress,
[User].UserId,
[User].UserName,
[User].FirstName,
[User].LastName,
UserRole.RoleId,
UserRole.RoleName,
Employee.EmployeeId,
Employee.EmployeeName,
Employee.JoinDate,
MAX(AuditTrail.LastLoginDate)
etc
问题:
- 我应该使用什么设计模式?
- 我应该能够编写多个查询,并在每个查询中检索到一堆混合和匹配列。也许,不是一个 将这种类型的结果集映射到 POCO 是个好主意 classes?
- 我可能有其他查询,这些查询或多或少需要与 SQL 结果集中的 return 相同类型的列。
- 我是否应该维护单独的实体来支持查询?
注意:我正在使用 Dapper ORM 与带有 .NET 4.5 Framework (C#) 的 SQL Server 2012 通信。 如果问题不清楚,请告知。
1) Repository和Unit of work模式适用于处理数据库CRUD操作。 2 + 4) DTO 和 POCO 基本上是一回事。其中 DTO 通常是用于存储数据的 POCO。使用它们是一种很好的做法,因为这样您就始终知道要使用的对象中有什么。如果您根据业务需求而不是数据库需求构建 DTO,那么在大多数情况下您根本不需要更改它 3) 问题是什么?
P.S。 关于在 .Net 环境中使用 SQL,我建议使用不太新的 SSDT 数据库项目。它将帮助您跟踪您的模式
您要找的模式是Data Mapper
A layer of Mappers (473) that moves data between objects and a database while keeping them independent of each other and the mapper itself.
这意味着持久层之外的东西不应该知道关于数据库的任何信息——ORM 框架和模仿 table 结构的 POCO 都不应该知道。
因此,在 DDD 的上下文中,这意味着您使用域模型并将 DB POCO 映射到该域模型。数据映射器负责该映射。
实施
您当然可以自己进行映射:在数据映射器中创建一个方法,该方法采用 DB POCO 和 returns 相应的域对象。但是,如果您有很多映射,则这需要大量样板代码。
为了缓解这种情况,请使用像 AutoMapper 这样的对象到对象映射库。它减少了您为映射编写的代码量,还使映射更易于维护。缺点是你必须学习一个新的库并依赖它。
DB POCO 管理
您的 DB POCO(许多人称为 DTO)应仅服务于一个目的:描述 table 的结构或 C# 世界中的结果集 - 仅此而已。所以是的,为每个查询创建一个 DB POCO returns 不同的结果结构。