代码之家  ›  专栏  ›  技术社区  ›  CTDev

如何使用实体框架构建具有“核心”数据库和单个派生数据库的ASP.NET MVC应用程序?

  •  2
  • CTDev  · 技术社区  · 6 年前

    我很难说出这个问题的名字和措辞,因为有很多东西要解开,所以我提前道歉-对于花时间回顾和回答这个问题的人,我非常感谢你。


    背景:

    我有一个相对较大的ASP.NET MVC5应用程序,使用实体框架6,使用一个SQL Server数据库。目前,该解决方案分为几个项目,主要按层(业务、数据等)进行划分。应用程序只有一个.edmx文件和dbContext,它目前指向一个数据库。

    上面的代码/解决方案表示正在构建的系统的“核心”。但是,这个应用程序是每个客户机定制的,因此每个客户机都可以有自己的模块、页面、逻辑等。因此,我们在每个客户机的解决方案中都有一个项目(现在只有两个,但最终将是50+—这是一个问题吗?把解决方案分开吧。其目的是能够只部署客户机的代码和核心,或者也能够只部署核心。

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


    这样,它基本上就是核心数据库,有可能为客户机的实现添加额外的对象。

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


    我的实施构想

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

    2 回复  |  直到 6 年前
        1
  •  3
  •   trailmax    6 年前

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

    一、 e.有一个控制器保存例如公司信息。每个人都得到相同的代码,但是如果客户BobTheBuilder Ltd.需要对公司进行特殊验证,那么该代码将进入 MyApp.BobTheBuilder.* 命名空间和配置代码应该知道应该执行此代码,而不是执行常规代码。不用说,这应该通过DI容器来完成,实现应该由注入实现公共接口的对象来代替。

    至于数据库-可以有多个表示数据库模块的数据库上下文。它们可以存在于同一个数据库中,但最好按模式名称来分隔模块。所以是的,所有这些对象都会转到代码库。只有不是每个租户都能得到所有的表-只有启用了的模块才应该被激活并创建他们的租户表。

    至于每个客户的项目-这也是一个很大的痛苦。想象一下如果你有超过10个客户并且需要更新 Newtonsoft.Json 包装-这通常需要比永远多一点!我们尝试了这一点,并返回到按客户重写的命名空间。

    • 租户都得到了相同的代码库,但是通过切换禁用了功能
    • 每个租户都有自己的数据库,其中包含所有表和启用的模式(模块)
    • CQRS是推荐的,但你可以没有它生活。尽管当你只需要考虑一小部分界面时,生活会轻松得多。
    • 我是必须的。如果没有一个支持多租户的好容器,就无法实现所有这些。
    • 有一些模块可以为每个客户开发一些特定的东西。每个模块都有自己的开关和非常可配置的——所以多个租户可以得到相同的模块,但是可以独立地重新配置。
        2
  •  1
  •   Jeremy Thompson    6 年前

    可以在ASP.NET MVC应用程序中使用实体框架实现继承:

    https://docs.microsoft.com/en-us/aspnet/mvc/overview/getting-started/getting-started-with-ef-using-mvc/implementing-inheritance-with-the-entity-framework-in-an-asp-net-mvc-application

    有几种方法 每个层次结构的表 (TPH)继承, 每种类型的表 每种混凝土等级的表

    如果您关心不同模式将如何集成,您还可以考虑使用微服务ie架构。

    实体框架似乎不会在上下文之间生成外键。