使用同一数据库将身份和业务操作的 DbContext 分开 - 有什么优势吗?

Separate DbContext for Identity and business operations with same database - is there any advantages?

我已经开始处理现有的 ASP.NET 使用身份框架的核心项目。该应用程序使用单个数据库。出于某种原因,应用程序使用两个单独的数据库上下文 - 一个派生自 IdentityDbContext,当然用于管理 User/Auth,另一个派生自 DbContext,用于除用户之外的任何其他用途-相关业务。

我以前见过应用程序使用两个单独的数据库上下文,但每次它们都通过 IdentityDbContext 使用单独的数据库。也许以前的开发人员试图实现一些我不清楚的东西。

那么,在我使用两个单独的上下文而应用程序只有一个数据库的情况下,我可能会遗漏哪些优势?谢谢。

编辑:

我的理解是,因为我只有一个数据库,所以我可以轻松地只使用 IdentityDbContext,它可以满足当前两个单独的上下文组合所服务的所有目的。该应用程序具有各种业务实体(比如员工、客户、供应商等),它们不属于该应用程序的 User,但可以在未来某个时间点通过注册相应级别的基于角色的权限而成为一个实体。在这种情况下,仅使用 IdentityDbContext 可以给我创建与 AspNetUsers table 的一对一关系的优势,我现在不能仅仅因为上下文不同而实现它。

唯一真正的 "advantage",而且它是轻微的,它更符合有界上下文的哲学:每个上下文应该只与特定的子域一起工作。但是,实际上,您还应该拥有单独的数据库,否则您仍然在混合上下文。此外,如果这一切都在同一个项目中,那么无论如何都是零分。在这种情况下,即使是限界上下文的想法也是一个有争议的问题,因为最终只有一个域。

这很可能是偶然而非故意的。当您使用个人用户帐户创建新项目时,会添加一个 IdentityDbContext 派生的 class,以支持脚手架。您可以简单地修改这个脚手架上下文以包含您自己的其他实体,但特别是更多绿色开发人员通常只会为应用程序的实体添加一个额外的上下文 class。他们都使用相同的底层数据库这一事实只会让人相信这很可能发生。

总之,没有真正的优势。唯一的好处是,如果您从字面上将这些上下文隔离开,使得两者永远不会同时用于同一项目,即它们位于单独的 class 库中,并且添加了一个或另一个引用,具体取决于该应用程序正在服务的特定域。否则就完全没有意义了。

这是基于单一职责和关注点分离的设计。

单独的上下文是不与其他上下文共享表的上下文。无论表格位于何处。

身份框架的职责是使用自己的上下文来识别用户。而应用程序具有存储业务相关数据的业务上下文。两者有不同的职责,除了可用于绑定两者的用户标识(或子声明)之外,这两个上下文实际上没有任何共同点。

简而言之,通过关注点分离,我可以在不破坏我的应用程序的情况下删除 Identity。换句话说,当我决定为像 IdentityServer4 这样的 sso 实现替换身份,转移职责时,我将毫不费力地将用户迁移到身份提供者的单独表中。

对于单个应用程序,您可能无法区分,但一旦应用程序成为更大平台的一部分,具有多个 api 或者当需要识别用户的责任时被替换,然后它会支付。

但对于单个应用程序,我也建议关注点分离。当上下文分离时,您将需要一个好的设计。它提高了可维护性并且更易于测试,因为身份的更改不会触及应用程序,反之亦然。

它还可以防止混合不应该混合的信息。例如。当您只想显示用户名时,您不想泄露散列密码。

出于安全原因,业务应用程序不应访问身份上下文,并且身份提供者应不知道业务上下文。如果信息丢失,那么您应该确保它成为上下文的一部分,而不是通过加入上下文。

混合上下文的问题在于,最终,所有内容都变成了一个上下文。这意味着很可能所有表都必须成为身份上下文的一部分。请阅读我的回答 以获得更多关于此的想法。

还要考虑单独的授权上下文。请阅读我的回答了解更多详情。