c# - 如何使用 Entity Framework 构建具有 "Core"数据库和各个派生数据库的 ASP.NET MVC 应用程序?

标签 c# asp.net sql-server visual-studio entity-framework

我很难命名和措辞这个问题,因为有很多东西需要解开,所以我提前道歉 - 对于任何花时间审查和回应这个问题的人,我非常感谢你。


背景:

我有一个相对较大的 ASP.NET MVC5 应用程序,使用 Entity Framework 6,并使用 SQL Server 数据库。目前,该解决方案被拆分为几个项目,大部分是按层(业务、数据等)拆分的。该应用程序有一个 .edmx 文件和 dbContext,目前它指向一个数据库。

上面的代码/解决方案代表了正在构建的系统的“核心”。然而,这个应用程序是根据每个客户端定制的,因此每个客户端都可以有自己的模块、页面、逻辑等。因此,我们在每个客户端的解决方案中都有一个项目(现在只有几个,但最终将是 50 个) + - 这是一个问题吗?也许可以将解决方案分开?)。目的是能够仅部署该客户端的代码以及核心,或者也能够仅部署核心。

除了代码中的自定义模块之外,它们还可能有自己的自定义数据库,同样源自核心数据库。自定义数据库将始终与核心数据库保持最新,但可能有其他对象(表、存储过程等)。需要注意的是,我无法选择放弃这种方法 - 每个客户肯定都会有自己的“核心”副本,但它将利用内部开发的推送工具保持最新。


问题/疑问:

这样,它本质上将成为核心数据库,并可能为该客户端的实现添加额外的对象。

我正在努力解决的问题是如何在 Entity Framework 中实现这一点,而不需要我将所有这些自定义数据库对象添加到核心数据库,或者至少让它们在逻辑上分离、降级到客户项目。解决这个问题的最佳方法是什么?


我的实现想法

这绝对是我目前正在努力的地方。我不太确定我当前的想法是否可行,但我仍在调查并试图提出更好的选择。

我当前的想法如下...因为我可以在生成 EDMX 时针对特定模式,将客户端特定对象放置在其项目的模式中,并利用这些对象在每个客户端项目/数据库中生成 dbContext,这继承自 Core 的 dbContext 实现(包含所有“核心”对象)。这意味着 ClientA 的项目将有一个 edmx 文件,其中仅包含其自定义表/对象,继承所有核心对象,但将它们与其他客户端的对象分开。

我不完全确定这种方法是否有效(现在就使用它),我最初担心的是 Entity Framework 似乎不会在上下文之间生成外键。例如,如果 ClientA 的表有一个指向核心表的外键,则生成工具似乎不会生成该关系。也就是说,我可以手动有效地实现这一点吗?核心代码首先是数据库,但是我可以先实现较小的、客户端特定的项目代码优先,我相信这会给我带来更大的灵活性。这是一种有效的方法吗?如果没有,我可以使用更好的方法吗?

最佳答案

作为一名处于非常相似情况的开发人员(为多个客户进行了 6 年的项目),我可以说你的方法充满了痛苦。为每个客户端定制代码是一条通往 hell 的道路。

您需要将相同的代码部署到每个客户端。核心保持不变。为特定客户开发的卫星模块应尽可能通用(以便您可以多次转售它们)并部署给每个人。诀窍是拥有一个良好的切换系统,该系统将只为每个客户端启用正确的功能。

即有一个 Controller 可以保存例如公司信息。每个人都获得相同的代码,但如果客户 BobTheBuilder Ltd. 需要对公司进行特殊验证,则该代码将进入 MyApp.BobTheBuilder.* 命名空间,并且您的配置代码应该知道应该执行该代码而不是你的通用代码。不用说,这应该通过 DI 容器完成,并且应该通过注入(inject)实现公共(public)接口(interface)的对象来替换实现。

对于数据库 - 您可以拥有多个代表数据库模块的数据库上下文。它们可以位于同一个数据库中,但最好按模式名称分隔模块。所以是的,所有这些对象都会进入您的代码库。只是并非每个租户都会获得所有表 - 仅应激活已启用的模块并创建其租户表。

至于每个客户的项目 - 这也是一个很大的痛苦。想象一下,如果您有超过 10 个客户并且需要更新 Newtonsoft.Json 包 - 这通常需要比永远更长的时间!我们尝试过,然后退回到每个客户的命名空间覆盖。

一般来说,这是我们的架构:

  • 租户都部署了相同的代码库,但功能被切换禁用
  • 每个租户都拥有自己的数据库,其中包含所有表和启用的架构(模块)
  • 不要为每个租户定制您的核心。所有定制都进入模块。
  • 建议使用 CQRS,但没有它也可以。尽管当您只需要考虑少数界面时,生活会容易得多。
  • DI 是必须的。如果没有支持 Multi-Tenancy 的良好容器,就无法实现这一切。
  • 有些模块可以执行针对每个客户开发的一些特定操作。每个模块都有自己的开关并且非常可配置 - 因此多个租户可以获得相同的模块,但可以独立地重新配置。

关于c# - 如何使用 Entity Framework 构建具有 "Core"数据库和各个派生数据库的 ASP.NET MVC 应用程序?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51831178/

相关文章:

sql-server - 故障转移后如何连接到镜像 SQL Server?

c# - Camel Case Web API Json 设置似乎不起作用

c# - Linq 从相邻列返回值

asp.net - HttpRequest的HttpMethod和RequestType有什么区别?

asp.net 核心身份和身份服务器

sql - ON [PRIMARY] 是什么意思?

sql-server - 查找具有相同订单的客户

c# - 如何使用 AuthenticationContext.AcquireTokenAsync 强制 AdminConsent?

c# - c#中的奇怪减法

c# - asp.net 文本框失去焦点的方法?