Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/284.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# EF'的单例范围;DBS上下文_C#_Asp.net Mvc_Entity Framework_Dependency Injection_Ninject - Fatal编程技术网

C# EF'的单例范围;DBS上下文

C# EF'的单例范围;DBS上下文,c#,asp.net-mvc,entity-framework,dependency-injection,ninject,C#,Asp.net Mvc,Entity Framework,Dependency Injection,Ninject,因此,我目前正在开发一个使用实体框架的ASP.NET MVC web应用程序,我还使用Ninject进行依赖项注入 所以基本上,目前,我就是这样向Ninject注册我的DbContext和服务的 kernel.Bind<DbContext>().To<MyApplicationContext>().InSingletonScope(); kernel.Bind<IAccountService>().To<AccountService>().InSi

因此,我目前正在开发一个使用实体框架的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();
然而,我有一种深刻的感觉,这个单例作用域将在我的web应用程序中引起问题,特别是对于实体框架的上下文,因为它是单例的

因此,我已经面临一个小问题,如果我使用SQL Management Studio手动更新数据库,我的web应用程序的实体框架中的数据在我重新启动应用程序之前不会更新(似乎是EF中的某种缓存机制)

--

但是,如果我删除SingletonScope中的
,我将从EF中随机获得错误,并指出:

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

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

我对依赖注入的理解仍然非常有限,所以有人能给我一些建议吗

--

编辑:我已尝试将所有注射更改为
在RequestScope
中,但我仍然得到

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

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


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

单例作用域对于您的上下文来说是一个非常糟糕的主意。请求范围是您应该使用的,因为它在请求的生命周期中本质上是一个单例

至于为什么在使用请求范围时会出现错误,我不能肯定。假设您正在使用的所有实体都来自相同的上下文类型,并且您在需要的任何地方都正确地注入了上下文,那么决不应该有多个上下文实例在起作用

编辑

重新阅读您的问题后,听起来好像您的服务实际上正在初始化其构造函数中的上下文或其他内容。如果是这样,那就是你的问题。您的上下文应该被注入到您的服务中,即:

public class AccountService : IAccountService
{
    protected readonly DbContext context;

    public AccountService(DbContext context)
    {
        this.context = context;
    }

    ...
}

然后,在更新任何服务时,Ninject将正确地注入请求范围内的
MyApplicationContext
实例。

Dan,当为整个应用程序定义单个
DBContext
的范围时,会造成瓶颈。在引擎盖下面,实体框架将相当有效地处理您需要多少对象。如果深入研究内部,与数据库联系的实际对象也会做同样的事情。因此,您试图通过创建一个单例来进行优化,实际上可能会产生一个非常大的问题。

我最终通过在RequestScope中使用
而不是在SingletonScope
解决了这个问题

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

因此,所有后续请求都使用最初缓存的实体对象,这就是为什么我从EF获得多个实例错误

--

如果你仍然面对

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


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

某些服务(包括
DbContext
生存期可以通过以下方式配置:


services.AddDbContext

是的,这就是我对服务所做的,注入DbContext。那么你是说我应该使用
InRequestScope()
来注册Ninject的所有服务,包括EF的DbContext?这还会导致什么问题?我在原始问题中提到的不同ObjectContext问题可以吗?对于web应用程序来说,几乎所有内容都应该是请求范围。由于像控制器这样的东西在每个请求中都是新的和被处理的,所以你总是会得到一份新的服务副本,或者任何能够在你在应用程序的其他区域之间传递以满足请求的东西。我已经试过了,看看我的问题编辑。。非常奇怪的问题,实体的关系有时没有填充(特别是第一次运行)并变为空..相关的:相关的:我想你正在经历。您可能将DbContext注入注册为singleton的使用者,导致DbContext也成为singleton。@Steven您是指空导航属性问题吗?我已经将每个使用者都更改为RequestScope,那么为什么它仍然是一个单例呢?我不熟悉导航属性问题,所以我无法对此发表评论,我也无法说明为什么以及消费者是否一直在使用DbContext,因为您还没有发布任何重现该问题的代码。Ninject缺乏为您找到这些的工具;您必须对此进行调试。这将起作用,但不是一个好主意,尤其是在ASP.NET应用程序中。我知道DBContext作为Singleton是一个非常糟糕的主意,但在我的情况下,由于处理时间过长,即使在请求结束后,我也需要保持服务运行。。由于dbcontext将在我的请求结束后处理,我尝试将其生存期更改为singleton,它的工作方式正是我所期望的。问题是,为什么这么糟糕?如果不是单例的话,在请求结束后如何访问dbcontext?
public class AccountService : IAccountService
{
    protected readonly DbContext context;

    public AccountService(DbContext context)
    {
        this.context = context;
    }

    ...
}