mongodb - 域对象中的关系引用 - 是否包含 Id?

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

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

领域对象应该不了解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 中,帖子和评论之间没有关系,任何帖子都包含评论列表,但评论本身不知道它们所属的帖子。 那么,使这些域类同时兼容基于 Sql 的数据库和 NoSql 数据库的最佳方法是什么?

谢谢

最佳答案

面向对象设计

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

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

因此,如果您想创建领域模型,请问自己以下问题:

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

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

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

文档数据库持久化

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

  • 将它们存储为单独的文档并相互引用
  • 将评论作为帖子的一部分存储在帖子文档中

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

关于mongodb - 域对象中的关系引用 - 是否包含 Id?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32306133/

相关文章:

javascript - 无法在 REST API 之外使用 Mongoose 查询 MongoDB

php - 预先声明所有私有(private)/局部变量?

oop - 抽象工厂是否引入紧耦合

mysql - 我正在尝试执行 mysql 查询以获取只供应红色部分的供应商?

javascript - 使用 Mongoose 时出现错误 'Object has no method xxx '

mongodb - 如果我可以使用 AWS 安全组来保护我的 MongoDB EC2 实例,我真的需要 VPC 吗?

javascript - 在 MongoDB 中使用嵌入式文档

php - 在 OOP php 中获取查询错误

sql - 我们可以将本地 SQL Server 数据库中的表连接到 Azure Delta Lake 中 Delta 表中的表吗?我有什么选择

mysql - 我们如何处理在表的所有记录中具有相同值的列?