存储库模式和 1:1 关系
我当前为每个数据库表创建一个存储库,并为列值(传递数据的对象)创建一个相应的数据类。
我最近开始使用一些一对一的关系,但我不确定实现它们的最佳方法是什么。
例如
如果我有一个 User 表和一个 UserSettings 表,两者之间存在 1:1 关系。
// Data classes (Holds all the field value for the table)
public class User
{
public int UserId { get; set; }
public string Name { get; set; }
}
public class UserSettings
{
public int UserId { get; set; }
public bool SomeSetting { get; set; }
}
问题:
- 我是否应该始终通过 User 对象来操作 UserSettings 对象,或者我应该能够操作它们 独立?
- 我应该在 UserSettings 对象中包含主键字段吗?
我应该在 User 对象中存储对 USerSettings 对象的引用吗?
我是否应该为 User 和一个 UserSettings 创建两个存储库,或者我是否处理 Users Repo 中的所有内容。
I currently create a Repository for each database table and a corresponding data class for the column values (object to pass around data).
I recently started using some 1 to 1 relationships and I'm not sure what would be the best way to implement them.
For example
If I have a User table and a UserSettings Table in a 1:1 relationship.
// Data classes (Holds all the field value for the table)
public class User
{
public int UserId { get; set; }
public string Name { get; set; }
}
public class UserSettings
{
public int UserId { get; set; }
public bool SomeSetting { get; set; }
}
Questions:
- Should I always go through the User object to manipulate the UserSettings object, or should I be able to manipulate them
independently? - Should I include the primary key field in the UserSettings object?
Should I store a reference to the USerSettings object in the User object?
Do I make two repo's one for User and one UserSettings, or do I handle everything in the Users Repo.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
我唯一一次发现聚合根之间的 1:1 关系有用是当关系两侧的聚合根由不同的域管理时。它们必须共享相同的主键,因此,如果它们都由同一域管理,那么根据定义,它们是同一聚合根的一部分。我认为您需要从不同的角度来解决这个问题:
User
对象是否仅针对此应用程序存在?如果
User
是一个完全驻留在该域内部的概念,则没有理由拥有与具有 1:1 关系的
;您只需将UserSettings
聚合根用户User.Settings
设置为检索该User
的UserSettings
的方法即可。 (当然,这消除了对存储库的需求 - 当UserRepository
水合User
上的其他所有内容时,它就成为了水合UserSettings
的责任。代码>。)但是,如果
用户
最终将通知多个域的会话,那么用户
需要代表它自己的域,您的应用程序将使用它。然后,您确实需要将此应用程序的UserSettings
与其他应用程序的 UserSettings 分开。User
并不是特定于该应用程序的,但该User
的UserSettings
是特定的。注意 - 为了避免在此时重构您的项目,如果上述问题 1 或 2 的答案为“否”,那么您应该< /strong> 将
UserSettings
设为同一域中的单独聚合根,以便在您最终将User
移动到其自己的域中时创建无缝过渡。The only time I've ever found a 1:1 relationship between aggregate roots to be useful is when the aggregate roots on either side of the relationship are managed by different domains. They must share the same primary key, and therefore if they are both managed by the same domain then they are by definition parts of the same aggregate root. I think you need to approach this question from a different angle:
User
object only going to exist for this application?If the
User
is a concept that resides entirely inside of this domain, then there's no reason to have aUserSettings
aggretate root that has a 1:1 relationship with aUser
; you simply makeUser.Settings
a way to retrieve theUserSettings
for thatUser
. (And of course that obviates the need for a repository - it becomes the responsibility of theUserRepository
to hydrate theUserSettings
when it hydrates everything else on theUser
.)But, if the
User
will eventually inform sessions for multiple domains, thenUser
needs to represent its own domain, the services of which your application will consume. Then, you gain a very real need to separate theUserSettings
of this application from those of a different application. TheUser
is not specific to this application, but theUserSettings
for thatUser
is.NOTE - In the interest of not refactoring your project at this point, if the answer to either question 1 or 2 above is "no", then you should make
UserSettings
a separate aggregate root within the same domain, in order to create a seamless transition when you eventually do moveUser
into its own domain.......
看来您正在采用自下而上(数据库优先/以数据库为中心)的方法,这在 DDD 中并不常见。正如“域驱动设计”这个名称所暗示的那样,您通常会从对域进行建模、充实您的聚合、聚合根和实体开始。
聚合根通常有自己的存储库,而常规实体通常没有。要知道一个实体是否应该是聚合根,您必须问自己该对象是否将成为应用程序中的主要入口点之一,一组相关对象围绕它,并且只能通过遍历它来获取。
用户显然是聚合根的候选者。相比之下,用户设置不是 IMO 的根,它属于用户的影响范围。我会将其作为用户聚合的一部分,并且只能通过遍历用户来获取。这意味着在 User 中引用 UserSettings,但不一定是相反。
...
It seems you're adopting a bottom-up (database first/database centric) approach which is uncommon in DDD. As the name Domain Driven Design implies, you usually rather start by modelling your domain, fleshing out your Aggregates, Aggregate Roots and Entities.
Aggregate roots usually have their own Repository while regular entities most often don't. To know whether an entity should be an Aggregate root, you have to ask yourself if that object is going to be one of the main entry points in the application, with a group of related objects gravitating around it and only obtainable through traversal of it.
User is an obvious candidate for an Aggregate root. User Settings in contrast isn't IMO a root, it belongs in the sphere of influence of a User. I'd make it a part of the User Aggregate and only obtainable through traversal of a User. It means having a reference to UserSettings in User but not necessarily the other way around.
我会问自己,UserSettings 是否可以在没有关联用户的情况下存在,和/或用户是否始终具有关联的 UserSettings。如果是这样,那么 UserSettings 可以很容易地成为 User 聚合的一部分,而不是本身成为一个单独的聚合。是的,在数据库中,它们很可能位于不同的表中,它们之间具有 1:1 的关系,但这是存储库实现的一个具体问题。您的域模型可以考虑用户的 UserSettings 部分。
I would ask yourself if a UserSettings can exist with out an associated user, and/or does a User always have an associated UserSettings. If so then the UserSettings could easily be made part of the User aggregate rather then being a separate aggregate itself. Yes in the database they will most likely be in different tables with 1:1 relationship between them, but this is a specific concern of the implementation of the repository. Your domain model could consider the UserSettings part of the user.