这里有一个有趣的情况。我们正在使用实体框架的存储库模式,因此每个数据库表都有自己的repository类,该类在其构造函数中接受DbContext的实例。我们还使用Ninject进行依赖注入。我们已经定义了要在给定请求期间实例化的单个上下文,以便当多个存储库请求DbContext时,始终使用相同的实例。这允许我们遵循一个UnitOfWork模式,这样多个事情可以在多个存储库中发生,并且一个提交将把所有更改提交到数据库。
这就是问题所在,我们也使用SQL Azure联邦,它将我们的客户端数据分割到多个数据库(分片)。我们需要能够在同一个请求中从一个联邦成员(数据库)跳转到另一个,但希望能够使用依赖于注入上下文的相同服务/存储库方法。我们的第一个想法是在现有上下文上执行USE FEDERATION sql命令以移动到下一个数据库,但它似乎有时可以工作,而有时则不行。在执行语句之后,我们看到上下文上的底层连接确实指向新服务器,但由于某种原因,在该上下文中执行的查询最终返回来自前一个连接的结果。我认为在多个数据库上使用上下文的相同实例并不是真正本地支持的东西,因为您通常会在连接到新数据库时启动新上下文。不幸的是,我们有一堆存储库是使用Ninject动态创建的,然后在相同的上下文实例中,所以即使我们为新数据库启动一个新的上下文,我们也无法使所有现有的存储库突然依赖于我们刚刚启动的新上下文,而不是在初始请求时创建的上下文。
这里有一些我们能想到的解决方案,但不确定如何使它们发挥作用:
- 更改在现有上下文中使用的数据库(如上所述,但似乎不起作用)
- 用一个新上下文替换所有存储库的注入上下文,这样所有现有存储库现在都依赖于一个不同的上下文
- 以某种方式从Ninject请求所有存储库的新实例,传递上下文所需的参数。
再次强调,这里的底线是我们有一组依赖于单个上下文的存储库和服务,我们希望能够重用这些服务和存储库,但要换出或更改所有依赖的上下文,以指向一个新的服务器。
解决方案是完全将Ninject从场景中删除。虽然不是最好的解决方案,但是我们使用的工具并不是真正设计用来在我们工作的环境中做我们想要的。