英文:
Splitting a big database into small DbContexts
问题
在我们公司,我们计划重新启动一个专有的ERP系统,而对于后端,我们将使用EFCore进行数据访问。
通常情况下,数据库设计并不是最佳的,但可以满足需求。但对于EFCore,我们面临一个问题,我们不确定如何处理。
我们希望为每个领域使用多个DbContext。但数据库跨越这些边界存在多个关系,并且每个表都位于同一个模式中。
如果我们迁移到代码优先,这样我们可以从代码中管理数据库,我们将无法管理所有关系,因为在DbContext中并不会使用每个关系。
-> 是否可能使用这种“不完整”的DbContext关系来使用代码优先来管理整个数据库?或者唯一的方法是拥有一个特殊的DbContext?还有其他方法吗?
因此,目前的替代方法似乎是完全采用反向工程将数据库转化为实体,并始终在数据库模式发生更改时覆盖实体(使用脚手架)。
我已经尝试创建一个单一的DbContext。通过这样做,我可以管理整个数据库,但这非常不愉快,上下文的创建时间非常长。
此外,我尝试创建多个上下文,但然后我无法管理不在DbContext中的关系。
目前,我们正在进行DbContext的反向工程,这非常有效。但我们需要在代码库之外管理数据库,这增加了部署和版本控制的复杂性。
英文:
In our company we are going to relaunch a proprietary ERP System and for the backend we will use EFCore for dataaccess.
As usual the database design is not the best, but will do the work. But for EFCore we are facing a problem we are unsure how to handle.
We would like to have multiple DbContexts for each domain. But the database does have multiple relations across these boundaries and every table is in the same scheme.
When we would migrate to code-first, so we can manage the db from code, we could not manage all relations because in a DbContext not every relation is used.
-> Is it possible to manage the whole db with those kind of "incomplete" DbContext-Relations with code-first? Or would be the only way to have one extraordinary DbContext? Or is there another way?
So for now the alternative seems to be to go all in for reverse engineering the db into entities and always let overwrite the entities (with scaffolding) when db scheme changes occur.
I already tried to create a single DbContext. With that I can manage the whole Db but it is very unpleasant and the creation of the context lasts horribly long.
Also I tried creating multiple Contexts but then I can not manage relations that are not inside a DbContext.
At this time we are reverse engineering the DbContexts, which works very well. But we need to manage the Database outside the codebase which does add complexity to deployment and versioning.
答案1
得分: 1
以下是翻译好的部分:
Is it possible to manage the whole db with those kind of "incomplete" DbContext-Relations with code-first? Or would be the only way to have one extraordinary DbContext? Or is there another way?
是否可以使用这种“不完整”的DbContext关系来使用code-first管理整个数据库?或者唯一的方式是拥有一个特殊的DbContext?还有其他方式吗?
Code-first or DB-first
The question around code-first vs db-first depends on which part of your system is considered the source of truth and which is an output artefact.
在code-first和db-first之间选择的问题取决于您的系统中哪个部分被视为真实数据源,哪个部分是输出产物。
In a DB-first approach, you maintain a database schema and the code is considered as an output of the scaffolding process. This code is usually considered disposable as you will re-scaffold it each time the db schema is updated. This scenario is well fitted for accessing legacy databases, or interop situations where you need finer control of the db scheme because multiple applications access the same database.
在DB-first方法中,您维护数据库架构,代码被视为脚手架过程的输出。通常将此代码视为一次性的,因为每次更新数据库架构时,您都会重新进行脚手架搭建。这种情况非常适合访问传统数据库或在多个应用程序访问同一数据库的互操作情况,因为您需要更精细地控制数据库架构。
In a code-first approach, your database schema is considered a disposable artefact. Its generated as an output of the application of db migrations orchestrated by EF core. This is well fitted for application that have an exclusive access to the database, as the database schema details are not really important as it's only purpose is to persist data of a given object model.
在code-first方法中,您的数据库架构被视为一种一次性工件。它是由EF Core协调的数据库迁移的应用程序的输出产物。这非常适合具有对数据库的独占访问权限的应用程序,因为数据库架构的详细信息并不是真正重要的,它的唯一目的是持久化给定对象模型的数据。
Single vs multiple contexts
To solve the problem of dbcontext too large, you can of course split your data access layer into multiple smaller contexts. In that context though, you are using EF core to access the database, not to persist a given object model. Doing code-first approach in that context is not coherent, and I would recommend you stick with db-first. This of course requires you to update the database scheme then rescaffold impacted contexts.
要解决DbContext过大的问题,您当然可以将数据访问层拆分为多个较小的上下文。但在这种情况下,您使用EF Core访问数据库,而不是持久化给定的对象模型。在这种情况下使用code-first方法是不一致的,我建议您坚持使用db-first方法。当然,这需要您更新数据库架构,然后重新进行脚手架搭建,以影响到的上下文。
As you already noted, EF core can only handle relationships between tables mapped by entities within their context. However there is no restriction on which tables get mapped to which contexts. Some may be bound multiple times. So for instance, Context 1 can access tables A and B, and Context 2 can access tables B and C. This way, you can handle all relationships in your database. However, this approach is even more incompatible with code-first approach, since you would have multiple sources of truth for a given table. Sticking with a db-first approach is fine though.
正如您已经注意到的,EF Core只能处理在其上下文中由实体映射的表之间的关系。但是对于哪些表映射到哪些上下文并没有限制。有些表可能会绑定多次。例如,上下文1可以访问表A和B,而上下文2可以访问表B和C。通过这种方式,您可以处理数据库中的所有关系。然而,这种方法与code-first方法更不兼容,因为对于给定表格,您将有多个真实数据源。不过,坚持使用db-first方法是可以的。
On a longer-term approach, you could try to split your database model into multiple separate schemas (if your RDBMS engine supports it) and try to work around the intricacies of relationships across them. Then move from the db-first approach to code-first. Beware such change is a very complex one at the business level and will introduce the kind of challenge you face when developing DDD / microservices applications.
在长期的方法上,您可以尝试将数据库模型拆分为多个单独的模式(如果您的RDBMS引擎支持),并尝试解决它们之间关系的复杂性。然后从db-first方法转向code-first方法。请注意,这种更改在业务层面上非常复杂,并且会引入您在开发DDD/微服务应用程序时面临的挑战。
英文:
> Is it possible to manage the whole db with those kind of "incomplete" DbContext-Relations with code-first? Or would be the only way to have one extraordinary DbContext? Or is there another way?
Code-first or DB-first
The question around code-first vs db-first depends on which part of your system is considered the source of truth and which is an output artefact.
In a DB-first approach, you maintain a database schema and the code is considered as an output of the scaffolding process. This code is usually considered disposable as you will re-scaffold it each time the db schema is updated. This scenario is well fitted for accessing legacy databases, or interop situations where you need finer control of the db scheme because multiple applications access the same database.
In a code-first approach, your database schema is considered a disposable artefact. Its generated as an output of the application of db migrations orchestrated by EF core. This is well fitted for application that have an exclusive access to the database, as the database schema details are not relly important as it's only prupose is to perist data of a given object model.
Single vs multiple contexts
To solve the problem of dbcontext too large, you can of course split your data access layer into multiple smaller contexts. In that context though, you are using EF core to access the database, not to persist a given object model. Doing code-first approach in that context is not coherent, and I would recommend you stick with db-first. This of course requires you to update the database scheme then rescaffold impacted contexts.
As you already noted, EF core can only handle relationships between tables mapped by entities within their context. However there is no restriction on which tables get mapped to which contexts. Some may be bound multiple times. So for instance, Context 1 can access tables A and B, and Context 2 can access tables B and C. This way, you can handle all relationships in your database. However, this approach is even more incompatible with code-first approach, since you would have multiple sources of truth for a given table. Sticking with a db-first approach is fine though.
On a longer term approach, you could try to split your database model into multiple separate schemas (if your RDBMS engine supports it) and try to work around the intrication of relationships accross them. Then move from the db-first approach to code-first. Beware such change is a very complex one at the business level and will introduce the kind of challenge you face when developping DDD / microservices applications.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论