#35481·efcore

开始引导用户远离 AddDbContext/OnConfiguring

作者: roji创建于 2025年1月15日更新于 2026年9月18日
标签needs-designarea-dbcontext

tl;dr 开始将用户移动到基于工厂的配置 DbContext 模式,停止依赖 EF 的内部服务提供商缓存来解决正确的服务提供商和单通资源. 这对支持Cosmos、PostgreSQL以及可能的其他供应商很重要。

当用户通过 AddDbContext/ Onconfigination 指定选项时,它们提供的设置选项的lambda 会被反复执行,可能会为不同的上下文产生不同的选项. 虽然这在某些情景中可能有用(例如为不同的租户指定不同的连接字符串),但也造成了重大问题. 为了正确支持这一点,EF管理一个在选项上按键的内部缓存,这样,如果(并且只有在)单通选项没有不同的值,就可以使用同一个服务商. 这反过来要求EF在进行缓存检查时总是能够比较这些选项;但提供者有任意的选项配置,这种配置可能根本不可比: Cosmos有CosmosClient Objects, EFCore. PG有CapitalData Source () (接受一个lobda来配置数据源)等.

我们讨论过这一点, 似乎大家普遍同意, 最好从这些有问题的配置机制开始, 转向基于工厂的 DbContext 即时化, 选择只计算一次, 然后用于所有的背景。

  • 目前,DI AddPooledDbContextFactory *只登记一个工厂(虽然未合并的AddDbContextFactory的确同时登记),使得使用起来更加困难(控制器不能直接被DbContext注入-不良好). #35484 记录DbContextFactory和IDbContextFactory在DI中同时注册的音轨——我认为这应该是确保良好经验的先决条件. *我认为这意味着我们最终会劝阻AddDbContext,并且建议用户总是使用AddDbContextFactory;这有点奇怪,因为用户不一定想要被注入AddDbContextFactory - 我们只希望他们使用一次计算选项的配置机制. 也许采用一个更优美的名字的新方法会更好(?).
  • 我们可以把这看作是一个仅作为文件/指导的过渡,或者更进一步的过渡;例如,当使用 AddDbContext/OnConfignation 时,我们可以从一个警告开始,逐渐向遗忘它们过渡,然后可能考虑我们是否真的想要删除它们. *一旦这一切完成,在使用上下文厂时,我们可以选择也禁用服务供应商缓存;工厂会直接"拥有"服务供应商,以及它内部的任何单顿资源.
  • 用户do 需要根据上下文不同选择(例如每个租户的连接字符串),理想的做法是有某种管理多个IDbContextFactories的机制——每个租户一个. 将租户身份映射到一个IDContextFactory的DI注册可以使这种经验好起来.
  • 注意到整个问题是: . . . . . . .