何时将某些实体分离到不同的存储库中?
我通常尝试将所有相关实体保存在同一个存储库中。 以下是两者之间有关系的实体(用缩进标记):
- 用户
- 用户偏好
因此,进入用户存储库是有意义的。 然而,用户通常链接到许多不同的实体,在以下示例中您会做什么?
用户
- 用户偏好
- 订单
订单
- 产品
订单与产品和用户都有关系,但您不会将所有 4 个实体的功能放在同一个存储库中。 当您与用户实体打交道并收集订单信息时,您会做什么? 您可能需要有关产品的额外信息,并且 ORM 通常会提供延迟加载的功能。 但是,如果您的产品实体位于与用户实体不同的存储库中,那么这肯定会导致存储库之间发生冲突吗?
I generally try and keep all related entities in the same repository. The following are entities that have a relationship between the two (marked with indentation):
- User
- UserPreference
So they make sense to go into a user repository. However users are often linked to many different entities, what would you do in the following example?
User
- UserPrefence
- Order
Order
- Product
Order has a relationship with both product and user but you wouldn't put functionality for all 4 entities in the same repository. What do you do when you are dealing with the user entities and gathering order information? You may need extra information about the product and often ORMs will offer the ability of lazy loading. However if your product entity is in a separate repository to the user entity then surely this would cause a conflict between repositories?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
在 Eric Evan 的领域驱动设计 ( http://domaindrivendesign.org/index.htm ) 中您应该首先考虑您的聚合的事情。 然后,您可以围绕这些构建存储库。
有许多技术可以处理彼此相关的聚合。 我最常使用的一种是只允许聚合通过只读接口相互关联。 聚合背后的关键思想之一是,如果不经过根,就无法更改底层对象的状态。 因此,如果产品和用户是模型中的根聚合,那么如果我通过用户->订单->产品到达产品,我将无法更新产品。 我必须从产品存储库获取产品才能对其进行编辑。 (从用户界面的角度来看,您可以让它看起来像用户->订单->产品,但是当您点击产品编辑屏幕时,您从产品存储库中获取实体)。
当您通过“用户”->“订单”->“产品”查看产品(以代码形式)时,您应该查看一个产品接口,该接口没有任何方法可以更改产品的基础状态(只能获取任何集合)等)
根据您的使用方式组织您的聚合和存储库。 我可以看到 User 和 Prodcut 是他们自己的聚合并拥有他们自己的存储库。 根据您的描述,我不确定订单是否应该属于用户或独立。
无论哪种方式,当聚合关联时都使用只读接口。 当您必须从一个聚合跨越到另一个聚合时,请从其自己的存储库中获取它。
如果您的存储库正在缓存,那么当您(通过用户)加载订单时,仅从数据库加载产品 ID。 然后使用产品 ID 从产品存储库加载详细信息。 您可以在加载订单时通过加载产品上的任何其他不变量来进行优化。
In the Eric Evan's Domain Driven Design ( http://domaindrivendesign.org/index.htm ) sense of things you should first think about what about your Aggregates. You then build you repositories around those.
There are many techniques for handling Aggregates that relate to each other. The one that I use most often is to only allow Aggregates to relate to each other through a read only interface. One of the key thoughts behind Aggregates is that you can't change state of underlying objects without going through the root. So if Product and User are root Aggregates in your model than I can't update a Product if I got to it by going through User->Order->Product. I have to get the Product from the Product repository to edit it. (From a UI point of view you can make it look like you go User->Order->Product, but when you hit the Product edit screen you grab the entity from the Product Repository).
When you are looking at a Product (in code) by going from User->Order->Product you should be looking at a Product interface that does not have any way to change the underlying state of the Product (only gets no sets etc.)
Organize your Aggregates and therefor Repositories by how you use them. I can see User and Prodcut being their own Aggregates and having their own Repositories. I'm not sure from your description if Order should belong to User or also be stand alone.
Either way use a readonly interface when Aggregates relate. When you have to cross over from one Aggregate to the other go fetch it from its own Repository.
If your Repositories are caching then when you load an Order (through a User) only load the Product Id's from the database. Then load the details from the Product Repository using the Product Id. You can optimize a bit by loading any other invariants on the Product as you load the Order.
你所说的存储库是指类吗?
根据对象(存储库)的使用,您可以创建一个组合数据库上数据的视图,并使用 ORM 创建一个类(存储库)来表示该视图。 当您想要显示每个表中仅几列的较轻量级对象时,此设计将起作用。
By repository you mean class?
Depending on the use of the objects (repositories) you could make a view that combines the data on the database and create a class (repository) with your ORM to represent that view. This design would work when you want to display lighter weight objects with only a couple columns from each of the tables.
如果 SQL Server 是您的数据库,并且存储库指的是数据库,那么我只需将信息粘贴到任何有意义的数据库中,并在依赖数据库中拥有一个视图,通过三点表示法从其他数据库中进行选择。
If SQL Server is your database, and by repository you mean a database, then I would just stick the information in whatever database makes sense and have a view in dependent databases that selects out of the other database via three-dot notation.
我仍然对“存储库”的含义感到困惑。 我会将您谈到的所有内容制作为单独的类(因此也是单独的文件),并且它们都位于同一个项目中。
I'm still confused by what you mean by "repository." I would make all of the things you talked about separate classes (and therefore separate files) and they'd all reside in the same project.