首页 > 解决方案 > 如何在单独的程序集中为 DbContext 扩展实体

问题描述

在我的用例中,我们有一个基线产品,它的架构考虑到了清洁架构原则。所以项目结构是这样的:

Src
|- Domain
|- Appllication
|- Persistence
|- Api
|- ...

我们使用 EF Core 作为持久层,每个实体都有 DbSetspublic DbSet<Customer> Customers {get;} 当然,我们有一个用于所有实体的接口。

虽然基础产品运行良好,但现在有一个客户需要定制,但不会在基础产品中实现。我怀疑未来会有更多需要个性化的客户。

我试图简单地为每个客户添加项目并覆盖现有的类/添加新的类。

Src
|- Domain
|- Appllication
|- ...
|- Customer1
  |- Domain
  |- Application
  |- ...

问题是,虽然我可以扩展Customer类(让我们CustomerExt从现在开始调用它),但 DbSet 接口当然仍然需要Customer该类。我可以用new关键字覆盖它,但随后 EF 抱怨说它需要一个鉴别器列。

System.InvalidOperationException: The discriminator value for 'CustomerExt' is 'Customer' which is the same for 'Customer'. Every concrete entity type in the hierarchy must have a unique discriminator value.

现在我质疑我使用客户特定项目和扩展其他项目的整个方法。虽然我可以“装饰”Customer类并简单地添加一个 FK,但我仍然认为这不是正确的方法。


标签: c#.net-corearchitectureentity-framework-corecustomization

解决方案


如果您打算这样做(支持“定制”),您需要进行更改以在工业规模上支持它。

至少有两家与我合作过的供应商使用功能开关来做到这一点——他们选择进行的任何定制都会成为一个代码库上的一个功能……所以没有定制,只有对唯一产品的扩展。

作为一家公司,您需要弄清楚这方面的标准是什么(关于通常会接受哪些更改以及为什么以及不接受哪些更改的指导)。您还需要开发一些模式,以便将来可以更轻松地进行类似的更改。

您需要检查您的架构,看看您现在可以支持哪些类型的更改,以及以后需要支持哪些类型的更改 - 以及这是否意味着任何重新架构。

然后,大多数设置作为功能/配置设置可供所有客户使用,但少数设置是隐藏的,仅用于“特殊”客户例外......使用相同的方法,但对“普通”客户不可见。

请记住,这不仅仅是代码和数据库的更改,还有文档、培训材料、单元测试,甚至营销,不要忘记运营支持、升级等。


推荐阅读