【问题标题】:Relational Reference in Domain Objects - Include Id or Not?域对象中的关系引用 - 是否包含 Id?
【发布时间】:2015-11-25 04:28:06
【问题描述】:

我想知道为我的项目设计域对象的最佳方式是什么。

领域对象应该不了解 ORM/Framework 甚至数据库技术(MySQL、MSSQL 甚至 Mongo)

想到下一个问题,假设我有两个对象,Post 和 Comment。

这是 Post 对象的代码:

class Post {
    public int Id { get; set; }
    public string Title { get; set; }
    public string Content { get; set; }
    public IList<Comment> Comments { get; set; }
}

现在,我对 Comment 对象的问题是它应该包含 Post Id 还是仅包含 Post 对象?

class Comment {
    public int Id { get; set; }
    public string Content { get; set; }
    public Post Post { get; set; }

    public int PostId { get; set; } // Should i include it?
}

包含关系对象的 Id 还是仅包含其域对象是一种好习惯?

另一个问题是没有像 mongodb 这样的 sql 数据库。 如果我将数据存储在 mongodb 中,Comment 对象将引用什么 Post 对象? 在 mongodb 中,post 和 cmets 之间没有关系,任何 post 都包含 cmets 列表,但 cmets 本身并不知道它们所属的 post。 那么,让这些领域类同时兼容基于 Sql 的数据库和 NoSql 数据库的最佳方法是什么?

谢谢

【问题讨论】:

  • 您想在设计中使用 DDD 吗?您添加了 DDD 标签,但问题似乎与 DDD 无关。请澄清。
  • 在 SO 上的一个问题中尽量避免这么多问题。您问题的第一部分(ID / 关系)与第二部分(mongoDB)无关,所以如果您提出多个单独的问题会更好。
  • @theDmi 那是个错误,我试图找到域对象的标签...我知道这些问题可能看起来不相关,但是这两个问题都围绕着什么是设计的最佳实践我的域对象。
  • “如果是好的做法吗?”,很抱歉告诉你这一点,但欢迎使用 NoSQL,因此最适合你的就是最好的,而不是要遵循的标准。另一方面,如果您尝试做一些可以很好地映射到关系和更多文档/对象存储域的事情,那么祝您好运,但至少从关系的角度来看,您可能需要在两端进行映射。什么是“良好实践”是做最适合您的应用程序的事情。理想情况下,您的对象应该与存储分离,但整个主题有点过于宽泛。

标签: mongodb oop relational-database non-relational-database database


【解决方案1】:

面向对象的设计

您设计了PostComment 类,使它们相互引用。虽然除非绝对必要,否则我会尽量避免这种紧密耦合,但它肯定会使Comment.PostId 过时,您可以在Comment 中调用Post.Id

此外,您的域对象可能应该尝试保护它们的不变量。您现在拥有的只是属性包(即使使用公共设置器),而不是域对象,因此目前它们与您用于持久性的对象相比没有任何有意义的优势。

所以如果你想创建一个领域模型,问自己这样的问题:

  • 演员可以对我正在构建的系统中的帖子做什么?
  • 演员可以检索评论中的哪些数据?

然后以支持您的业务案例的方式为您的域对象建模。例如,如果您的应用程序的用户被禁止更改帖子的标题,您应该从 Post.Title 中删除 setter。

This answer 可能会为您提供有关域对象和简单属性包(又名 POCO)之间区别的更多信息,即使该答案是在域驱动设计的上下文中。

文档数据库持久性

要将这些对象存储在面向文档的数据库中,您基本上有两种选择:

  • 将它们存储为单独的文档并相互参考
  • 将 cmets 作为帖子的一部分存储在帖子文档中

这两种方法都是有效的,您必须根据自己的应用来决定。但是请注意,文档边界也是一致性边界,因此如果您需要对帖子及其 cmets 进行原子操作,您唯一的选择是将它们放在同一个文档中。

【讨论】:

  • 感谢您的评论。我不明白你所说的我的对象不是域对象是什么意思,你能解释一下吗?
【解决方案2】:

绝对应该包含它。如果您想获取 cmets 列表但又不想获取每个评论的 Post 对象,但仍需要 PostID,该怎么办?

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-08-12
    • 1970-01-01
    • 2015-08-27
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多