【发布时间】:2019-01-20 16:56:56
【问题描述】:
我很难为这个问题命名和措辞,因为有很多东西要解开,所以我提前道歉 - 对于任何花时间审查和回复这个问题的人,我非常感谢你。
背景:
我有一个相对较大的 ASP.NET MVC5 应用程序,使用 Entity Framework 6,使用 SQL Server 数据库。目前,该解决方案分为几个项目,主要是按层(业务、数据等)拆分。应用程序只有一个 .edmx 文件和 dbContext,它目前指向一个数据库。
上面的代码/解决方案代表了正在构建的系统的“核心”。然而,这个应用程序是为每个客户定制的,因此每个客户都可以有自己的模块、页面、逻辑等。因此,我们在解决方案中为每个客户都有一个项目(现在只有几个,但最终会是 50 + - 这是一个问题吗?也许可以拆分解决方案?)。目的是能够仅部署该客户端的代码以及核心,或者也能够仅部署核心。
除了代码中的自定义模块外,它们还可能有自己的自定义数据库,同样源自 Core 数据库。自定义数据库将始终与核心数据库保持同步,但可能有其他对象(表、存储过程等)。需要注意的是,我没有选择放弃这种方法 - 每个客户肯定会有自己的“核心”副本,但会使用内部开发的推送工具保持最新。
问题/疑问:
这样,它本质上就是核心数据库,可能会为该客户端的实现添加额外的对象。
我正在努力解决的问题是如何在 Entity Framework 中以一种不需要我将所有这些自定义 db 对象添加到 Core 数据库的方式来实现它,或者至少让它们在逻辑上分离、降级到客户项目。解决此问题的最佳方法是什么?
我的实施想法
这绝对是我目前苦苦挣扎的地方。我不确定我目前的想法是否可行,但我仍在调查并试图提出更好的选择。
我目前的想法如下......因为我可以在生成 EDMX 时以特定模式为目标,所以将客户特定对象放置在他们项目的模式中,并利用这些对象在每个客户项目/数据库中生成一个 dbContext,这继承自 Core 的 dbContext 实现(包含所有“核心”对象)。这意味着 ClientA 的项目将有一个仅包含其自定义表/对象的 edmx 文件,继承所有核心对象,但将它们与其他客户端的对象分开。
我不完全确定这种方法是否可行(现在正在使用它),我最初担心的是实体框架似乎不会在上下文之间生成外键。例如,如果 ClientA 的表具有指向核心表的外键,则生成工具似乎不会生成该关系。也就是说,我可以有效地手动实现吗?核心代码是数据库优先,但是我可以先实现较小的、客户特定的项目代码,我相信这会给我更大的灵活性。这会是一种有效的方法吗?如果没有,我可以使用更好的方法吗?
【问题讨论】:
-
为每个客户做一个自定义数据库将是地狱。您可以为每个客户提供不同的数据库,但让他们都使用相同的设计。我的公司以这种方式拥有 7,000 个数据库。它们曾经是定制的,我听到关于它有多糟糕的恐怖故事。
-
我遇到的问题是我不一定有一个选项——这个应用程序的每个客户端的实例都是独立的——他们有自己的数据库、Web 服务器等实例。核心代码仍然存在同样,我们部署到所有这些环境(是的,这很痛苦),但是自定义模块等也需要能够推送到各个客户端。
-
是的,你有一个选择。停止为每个客户端做自定义数据库。您可以拥有单独的实例,而无需自定义它们。如果你走自定义路线,你会把自己置于一个痛苦的世界中。把所有需要的功能都放到标准数据库中,让每个人都使用标准数据库。使用功能切换来控制实际最终使用的功能。不要为每个客户做一个分支 - 为一个功能做一个分支。
-
对不起,我应该更清楚一点 - 当我提到缺少选项时,我的意思更多是作为管理层的指令,因为他们不希望任何给定客户端的数据库中未使用的实体。也就是说,今天早上与他们交谈时,我能够说服他们,在客户端 B 的数据库中拥有客户端 A 的实现中未使用的实体比必须将它们作为单独的数据库进行管理要好。所以这大大简化了这一点,我仍然有一些事情需要与他们澄清,稍后可能会在这更清楚后回到 SO。
-
干得好!不要把管理层所说的一切都视为理所当然——他们并不总是知道与他们的决策相关的成本。如果你能向他们展示为什么要以另一种方式做事的充分理由,他们会经常倾听。我的公司有三种不同类型的应用程序。我们将每个客户或设施拆分到他们自己的数据库中。一个应用程序有 7,000 个数据库,另一个有 600 个,另一个有 70 个。我们永远无法像您所说的那样管理它们。
标签: c# asp.net sql-server visual-studio entity-framework