带有Ninject和EF Core的MVC 5,Context在一次查询后抛出异常

问题描述 投票:1回答:2

我正在尝试使用Framework 4.6.1在我们的ASP.Net MVC 5 Web应用程序中使用EF Core。我们正在使用Ninject进行依赖注入。我在DAL层注入了Context。我成功执行单个查询,但上下文在运行下一个查询时抛出以下异常

没有为此DbContext配置数据库提供程序。可以通过覆盖DbContext.OnConfiguring方法或在应用程序服务提供程序上使用AddDbContext来配置提供程序。如果使用AddDbContext,那么还要确保您的DbContext类型在其构造函数中接受DbContextOptions对象,并将其传递给DbContext的基础构造函数。

我以前见过这个错误,但我不确定它在我的情况下是如何适用的。什么是我的设置导致此错误被抛出?这是一些代码:

控制者:

public ActionResult GetEnrollmentWorkflows()
{
    var class1Entities = this._class1Service.GetAll().ToList();
    var class1EntityIds = class1Entities.Select(x => x.Class1EntityId).ToList(); // Works
    var class2Entity =
        this._class2EntityService
            .GetByClass1EntityIds(class1EntityIds).ToList(); // Fails with exception
    return PartialView("_somePartial", model);
}

上下文绑定:

kernel.Bind<Context.ContextTenant>().ToSelf().InTransientScope()
    .WithConstructorArgument("options",
        new DbContextOptionsBuilder<Tables.ContextTenant>()
    .UseSqlServer(ConfigurationManager.ConnectionStrings
        [EnvironmentConsts.DbConnectionTenant].ConnectionString)
    .Options);

上下文:

public ContextTenant(DbContextOptions<Tables.ContextTenant> options) : base(options)
{}

protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
{
    base.OnConfiguring(optionsBuilder);
}

Ninject模块:

public class DalModule : NinjectModule
{
    public override void Load()
    {
        this.Kernel.Bind(x =>
            x.FromThisAssembly().SelectAllClasses().Join
                .FromAssemblyContaining<ISomeInterface>()
                .SelectAllInterfaces()
                .BindAllInterfaces().Configure(y => y.InTransientScope()));
    }
}



public class ServiceModule : NinjectModule
{
    public override void Load()
    {
        this.Kernel?.Load(new[] { new DalModule() });
        this.Kernel.Bind(x =>
            x.FromThisAssembly().SelectAllClasses().Join
                .FromAssemblyContaining<ISomeInterface>()
                .SelectAllInterfaces()
                .BindAllInterfaces().Configure(y => y.InTransientScope()));
    }
}

DAL课程

1类:

public class Class1Repository : IClass1Repository
{
    private ContextTenant ContextTenant { get; }

    public Class1Repository(ContextTenant contextTenant)
    {
        ContextTenant = contextTenant;
    }

    public IEnumerable<Class1Entity> GetAll()
    {
        return this.ContextTenant.Class1Entity.Select(x => x);
    }
}

第2类:

public class Class2Repository : IClass2Repository
{
    private readonly ContextTenant _contextTenant;

    public Class2Repository(ContextTenant contextTenant)
    {
        _contextTenant = contextTenant;
    }

    public IEnumerable<Class2Entity> GetByClass1EntityIds(
        IEnumerable<int> class1EntityIds)
    {
        return this._contextTenant.Class2Entity.Where(x =>
            class1EntityIds.Contains(x.Class1EntityId));
    }
}

服务:

public class Class1Service : IClass1Service
{
    private readonly IClass1Repository _class1Repository;

    public Class1Service(IClass1Repository class1Repository)
    {
        _class1Repository = class1Repository;
    }

    public IEnumerable<Class1Entity> GetAll()
    {
        return this._class1Repository.GetAll();
    }
}

public class Class2Service : IClass2Service
{
    private readonly IClass2Repository _class2Repository;

    public Class2Service(IClass2Repository class2Repository)
    {
        _class2Repository = class2Repository;
    }

    public IEnumerable<Class2Entity> GetByClass1EntityIds(
        IEnumerable<int> class1EntityIds)
    {
        return this._class2Repository.GetByClass1EntityIds(class1EntityIds);
    }
}

编辑:以下是一些来自启动的代码,以防这会影响任何事情:

[assembly: WebActivatorEx.PreApplicationStartMethod(typeof(NinjectWebCommon), "Start")]
[assembly: WebActivatorEx.ApplicationShutdownMethod(typeof(NinjectWebCommon), "Stop")]
namespace MyApp
{
    public static class NinjectWebCommon
    {
        private static readonly Bootstrapper bootstrapper = new Bootstrapper();

        public static void Start()
        {
            DynamicModuleUtility.RegisterModule(typeof(OnePerRequestHttpModule));
            DynamicModuleUtility.RegisterModule(typeof(NinjectHttpModule));
            bootstrapper.Initialize(CreateKernel);
        }

        public static void Stop()
        {
            bootstrapper.ShutDown();
        }

        private static IKernel CreateKernel()
        {
            // Bind the context
        }
    }
}
c# asp.net-mvc-5 entity-framework-core ninject .net-4.6.1
2个回答
0
投票

根据我上面的内容,我相信这是因为您正在使用RequestScope。问题是db context将在每次使用后进行处理,因为你仍然在同一个请求中,当你再次调用它时它已经被处理掉了,但它却服务于同一个实例。将其更改为Transient(或与Ninject等效的Transient,意味着在每个请求上获取新的db上下文),它应该解决问题。


0
投票

我过去遇到过类似的问题,有时可以通过改变来解决

protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
{
    base.OnConfiguring(optionsBuilder);
}

protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
{
    if (optionsBuilder.IsConfigured == false)
    { 
        base.OnConfiguring(optionsBuilder);
    }
}
© www.soinside.com 2019 - 2024. All rights reserved.