我正在努力更好地理解域驱动设计中的存储库模式。存储库模式实现的所有示例仅处理实体。但是,如果我只需要检索实体的某些部分呢?例如,我有具有大量属性的客户端实体。我可以在ClientRepository中定义类似的内容:
public IEnumerable<string> GetClientsNames() { ... }
甚至:
class ClientBaseInfo //includes some subset of properties of Client entity
{
public string Name {get; set;}
public string Surname {get; set;}
public int Age {get; set;}
public string Email {get; set;}
}
....
public IEnumerable<ClientBaseInfo> GetClientsBaseInfo() { ... }
这种实施的原因是性能。无论如何,我认为我的代码将被这种“部分实体”污染。这种方法在现实生活中是以某种方式使用的吗?或者避免加载重实体的唯一方法是拆分表及其对应的实体或其他什么?
编辑:是的,我说的是像DTO这样的东西。我怀疑存储库是用于处理这种对象,还是仅用于业务实体。我可以为特定情况定义许多不同的DTO,但是我的代码可能变得太复杂了吗?我没有答案,因为我没有经验。我想知道有经验的人的意见。
答案 0 :(得分:5)
对于这些类型的查询,建议的方法是使用读取模型(CQRS样式)。
因此,您可以实现一个非常精简的查询图层,该图层返回原始结构,以满足您的目的。在c#世界中,我选择从DataRow
到DataTable
到DTO的任何内容(对于更复杂的结构)。
请记住,读取模型并不意味着最终的一致性,并且您的查询方可以处于同一表/数据库中100%一致性到另一个数据库中最终一致性的任何级别。
因此,这些类型的查询不一定适合存储库模式。
答案 1 :(得分:1)
它一如既往地依赖。
您的业务逻辑不应该依赖于数据库结构。
它应代表您的业务逻辑。这意味着,在设计实体及其关系时需要小心。
另一方面,它取决于您为什么只需要加载实体属性的一部分。
如果你在一个类中有这么多属性,也许你应该更改域逻辑?
也许你需要Data Transfer Objects?
您可以创建 DTO 类,它只是传输数据的实体的“简单版本”?
<强>更新强>
您可以在存储库中使用dto。在某些情况下,它需要(报告等)。
以下是 NHibernate
的一些示例NHibernate QueryOver projections - projecting collections to DTO
Fill property of DTO with SubQuery in NHibernate Query
这种方法在少数情况下是可以接受的。
如果您需要在应用程序中使用dto,则表示您需要更改域层。
也许您应该将您的班级划分为较小的班级并单独加载。