EF的DbContext的单例范围

Dan*_*Dan 5 c# asp.net-mvc entity-framework dependency-injection ninject

所以我目前正在使用一个使用Entity Framework的ASP.NET MVC Web应用程序,我也使用Ninject进行依赖注入.

所以基本上,目前,这是我用Ninject注册我的DbContext和服务的方式.

kernel.Bind<DbContext>().To<MyApplicationContext>().InSingletonScope();
kernel.Bind<IAccountService>().To<AccountService>().InSingletonScope();
kernel.Bind<IRegionService>().To<RegionService>().InSingletonScope();
kernel.Bind<IRoleService>().To<RoleService>().InSingletonScope();
Run Code Online (Sandbox Code Playgroud)

我注册它们InSingletonScope,这意味着它们只会被创建一次并在应用程序的整个生命周期中使用(至少我是如何理解的).

控制器:

private IAccountService _accountService;

public MemberController(IAccountService accountService)
{
    _accountService = accountService;
}
Run Code Online (Sandbox Code Playgroud)

但是,我深深感到这个单例范围会导致我的Web应用程序出现问题,特别是对于Entity Framework的上下文,因为它是单例.

我已经面临一个小问题,如果我使用SQL Management Studio手动更新数据库,我的Web应用程序的实体框架中的数据将不会更新,直到我重新启动应用程序(似乎是EF中的一些缓存机制).

-

但是,如果我删除了InSingletonScope,我将随机从EF获取错误说:

IEntityChangeTracker的多个实例不能引用实体对象

我理解为什么会发生这种情况,因为初始化的DbContext AccountService可能与说不同RegionService.但我不知道如何解决这个问题.

我对依赖注入的理解仍然非常有限,所以有人可以建议吗?

-

编辑:我已经尝试改为InRequestScope所有注射,但我仍然得到

IEntityChangeTracker的多个实例不能引用实体对象

尝试从我的应用程序中的另一个服务插入具有相关对象(外键)的新实体时.这意味着他们仍在使用不同的DbContext,发生了什么?!

最后编辑:好的我发现了问题,这是我的缓存机制缓存了以前的请求,导致所有后续请求的关系问题.

Ham*_*med 7

lifetime一些服务,包括DbContext可以这样配置:

services.AddDbContext<ApplicationDbContext>(
    options => { options.UseSqlServer("YourConnectionString"); },
    ServiceLifetime.Singleton);
Run Code Online (Sandbox Code Playgroud)

参考文献

  • 这可以工作,但不是一个好主意,尤其是在 ASP.NET 应用程序中。 (2认同)
  • 我知道 DBContext 作为 Singleton 是非常糟糕的主意,但就我而言,即使在请求结束后,由于处理时间过长,我也需要保持服务运行。并且由于 dbcontext 将在我的请求结束后处置,我尝试更改其生命周期到单身人士,它的工作原理正是我所期望的。问题是,为什么这么糟糕?如果不应该是单例的,我如何在请求结束后访问 dbcontext? (2认同)

Dan*_*Dan 3

我终于设法通过使用InRequestScope而不是解决了这个问题InSingletonScope

InRequestScope最初,由于我的服务层上现有的缓存机制,我在更改后仍然面临同样的问题。

因此,所有后续请求都使用最初缓存的实体对象,这就是我从 EF 收到多个实例错误的原因。

--

如果您仍然面临着

实体对象不能被 IEntityChangeTracker 的多个实例引用

更改为 后出错InRequestScope,请确保您的实体没有以某种方式缓存或存储以供后续 HTTP 请求使用。