拥有多个实体上下文

Having more than one entity context

假设我已经扩展了 identity framework dbContext 来构建我自己的,并且我有我们经过身份验证的控制器,它被注入 dbContext 并获取与当前的 ApplicationUser、entity framework 将关联两个实体,由于循环引用而导致服务器错误。

我们不想序列化循环引用。

所以我们在实例化一个新的dbcontext的方法中创建一个新的dbContext并查询不相关的实体,这将起作用。但是这是不可测试的,我们不希望我们的控制器严格依赖dbContext,我们希望它被注入。

所以我们在构造函数中添加第二个参数,不幸的是这会使系统注入相同的dbContext两次,不是那么有用。

我们试图创建一个继承自dbContext的classfakeDbContext并添加服务并使用它,但现在我们有两个dbcontext,谁可能会产生迁移、配置和错误...

在新的 MVC6 中执行此操作的正确方法是什么?

编辑...

我发现如果我的控制器需要 IEnumerable<dbContext>,我会将所有对象注册为该类型的服务,所以只需将 startup.cs[=69 中的部分加倍=] 我们在服务注册区添加 dbContext 的地方我得到了两个...

这里的缺点是我不知道哪个是virgin,看起来是按照注册的顺序,但我不知道,如果这个会改变。

编辑 2 ...

我创建了一个 TransientDbService class,它只有一个采用 IserviceProvider 的工厂方法,它使用它来获取构建 dbContext 的选项,然后暴露它。我已将其注册为瞬态,然后在控制器中我需要此服务类型。

这里的缺点是如果我需要第三个 dbContext 我应该写更多的代码,更多的代码意味着错误和维护它。

编辑 3 ...

根本没有两个 dbContext。以下设置允许我没有任何关系。

Database.ChangeTracker.QueryTrackingBehavior = Microsoft.Data.Entity.QueryTrackingBehavior.NoTracking;

这里的缺点是我不能使用我的模型图,使一切变得更加复杂...

编辑 4 ...

https://github.com/aspnet/DependencyInjection/issues/352

您认为在某些情况下没有跟踪查询会有帮助是正确的,但在其他时候您需要创建多个 DbContext 实例。

您通常在启动时使用 AddDbContext<TContext>() 方法来确保根据请求创建上下文类型的实例,并在其上设置正确的 DbContextOptions 和服务提供商。当您需要偏离此模式时,您有几个选择,例如:

  1. 在派生的 DbContext class 中包含一个构造函数,该构造函数采用 IServiceProvider 并将其传递给基本构造函数。确保您的控制器占用 IServiceProvider。执行此操作后,您应该能够使用以下内容手动创建 DbContext

    using(var context1 = new MyDbContext(serviceProvider), var context2 = new MyDbContext(serviceProvider)) { ...

  2. 为了避免必须更改派生的 DbContext 类型的构造函数签名,您可以利用 DbContextActivator class(这是我们的内部命名空间) , 例如:

    using(var context1 = DbContextActivator.CreateInstance<MyDbContext>(serviceProvider), var context2 = DbContextActivator.CreateInstance<MyDbContext>(serviceProvider) {...

注意:如果您在启动时仍在使用 AddDbContext<MyDbContext>(options => ...),它应该会自动从服务提供商处提取这些选项。但是您也可以选择将 DbContextOptions 作为参数包含在构造函数中,或者为此覆盖 OnConfiguring() 方法。

我给你的例子是在 using 块中创建两个单独的 DbContexts,但你也应该能够将它们与常规的 "per-request" DbContext 混合,你将在控制器的构造函数中注入.

除了这些当前可用的选项之外,我还创建了一个新问题来跟踪有关如何在同一请求中创建相同 DbContext 类型的多个实例的其他可能的改进:

https://github.com/aspnet/EntityFramework/issues/4441