【问题标题】:Can repository pattern be used for loading of "partial entities"存储库模式可以用于加载“部分实体”吗
【发布时间】:2014-07-22 21:20:01
【问题描述】:

我试图更好地理解领域驱动设计中的存储库模式。存储库模式实现的所有示例都仅处理实体。但是如果我只需要检索实体的一部分呢?例如,我有具有大量属性的客户端实体。我可以在 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,但是我的代码会变得太复杂吗?我没有答案,因为我没有足够的经验。我想知道有经验的人的意见。

【问题讨论】:

  • 你不应该颠倒继承概念
  • 你能定义“大量的属性”吗?当您从 Repo 中获取 Aggregate Root 时,它应该被完全加载。如果它太大,也许你应该考虑改变你的聚合设计。

标签: c# entity domain-driven-design repository-pattern


【解决方案1】:

对于这类查询,建议的方法是使用读取模型(CQRS 样式)。

因此,您可以实现一个非常薄的查询层,该查询层返回原始结构以满足您的目的。在 c# 世界中,我选择从 DataRow 到 DataTable 再到 DTO(对于更复杂的结构)。

请记住,读取模型并不意味着最终一致性,您的查询端可以处于任何级别,从同一个表/数据库中的 100% 一致性到另一个数据库中的最终一致性。

因此,这些类型的查询并不适合存储库模式。

【讨论】:

【解决方案2】:

这总是取决于,像往常一样。

您的业务逻辑不应依赖于数据库结构。

它应该代表您的业务逻辑。这意味着,您在设计实体及其关系时需要小心。

另一方面,这取决于您为什么只需要加载实体的一部分属性。

如果你在一个类中有这么多属性,也许你应该改变领域逻辑?

也许您需要Data Transfer Objects?

您可以创建 DTO 类,这将是您的实体的“简单版本”,只是为了传输数据?

更新:

您可以在存储库中使用 dto。在某些情况下,它是需要的(报告等)。

以下是 NHibernate

的一些示例

NHibernate QueryOver projections - projecting collections to DTO

Fill property of DTO with SubQuery in NHibernate Query

这种方法在少数情况下是可以接受的。

如果您需要在整个应用程序中使用 dto,则意味着您需要更改域层。

也许你应该把你的类分成更小的类并分别加载它们。

【讨论】:

    猜你喜欢
    • 2010-10-24
    • 1970-01-01
    • 2011-07-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-05-18
    • 1970-01-01
    相关资源
    最近更新 更多