在Entity Framework Core中从cookie和基本路径创建数据库上下文 [英] Create database context from cookie and base path in Entity Framework Core

查看:41
本文介绍了在Entity Framework Core中从cookie和基本路径创建数据库上下文的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

Postgres数据库具有多个方案,例如company1,company2,... companyN

Postgres database has multiple schemes like company1, company2, ... companyN

浏览器发送包含方案名称的cookie.数据访问操作应在此方案中发生.Web应用程序用户可以选择不同的方案.在这种情况下,将设置不同的cookie值.

Browser sends cookie containing scheme name . Data access operations should occur in this scheme. Web application user can select different scheme. In this case different cookie value is set.

使用了Npgsql EF核心数据提供程序.

Npgsql EF Core Data provider is used.

ASP NET MVC 5 Core应用程序在StartUp.cs中注册工厂:

ASP NET MVC 5 Core application registers factory in StartUp.cs :

    public void ConfigureServices(IServiceCollection services)
    {
        services.AddHttpContextAccessor();
        services.AddScoped<IEevaContextFactory, EevaContextFactory>();
      ....

家庭控制器尝试使用它:

Home controller tries to use it:

public class HomeController : EevaController
{
    public ActionResult Index()
    {
        var sm = new SchemeManager();
        sm.PerformInsert();
    ....

由于工厂成员为null,因此将引发异常.如何解决这个问题?

This throws exception since factory member is null. How to fix this ?

public interface IEevaContextFactory
{
    EevaContext Create();
}

public class EevaContextFactory : IEevaContextFactory
{
    private IHttpContextAccessor httpContextAccessor;
    private IConfiguration configuration;

    public EevaContextFactory(IHttpContextAccessor httpContextAccessor, IConfiguration configuration)
    {
        this.httpContextAccessor = httpContextAccessor;
        this.configuration = configuration;
    }

    public EevaContext Create()
    {
        var builder = new DbContextOptionsBuilder<EevaContext>();
        var pathbase = httpContextAccessor.HttpContext.Request.PathBase.Value;
        var scheme = httpContextAccessor.HttpContext.Request.Cookies["Scheme"];

        var csb = new NpgsqlConnectionStringBuilder()
        {
            Host = pathbase,
            SearchPath = scheme
        };
        builder.UseNpgsql(csb.ConnectionString);
        return new EevaContext(builder.Options);
    }
}

方案数据访问方法:

public class SchemeManager
{
    readonly IEevaContextFactory factory;

    public SchemeManager(IEevaContextFactory factory)
    {
        this.factory = factory;
    }

    public SchemeManager()
    {
    }

    public void PerformInsert()
    {
        using (var context = factory.Create())
        {
            var commandText = "INSERT into maksetin(maksetin) VALUES (CategoryName)";
            context.Database.ExecuteSqlRaw(commandText);
        }
    }
}

推荐答案

var sm = new SchemeManager()

...将在SchemeManager上调用无参数构造函数,因此不会注入IEevaContextFactory.您应该将工厂注入控制器,然后将其传递给SchemeManager.

... will call the no-parameter constructor on SchemeManager so the IEevaContextFactory is not injected. You should inject your factory into your controller and pass it into your SchemeManager.

删除您的无参数构造函数.不需要.

Remove your no-parameter constructor. It's not needed.

public class HomeController : EevaController
{
    private IEevaContextFactor eevaFactory;
           
    public HomeController(IEevaContextFactory factory)
    {
         eevaFactory = factory;
    }
        
    public ActionResult Index()
    {
         var sm = new SchemeManager(eevaFactory);
         sm.PerformInsert();
         ....
    }
}

您的另一个选择是将SchemeManager放入DI容器中,然后DI容器将在构造函数上自动解析IEevaContextFactory,然后将SchemeManager注入到您的控制器中.

Your other option is to put the SchemeManager in the DI container and then the DI container will auto-resolve IEevaContextFactory on the constructor and then just inject SchemeManager into your controller.

无论哪种方式,都删除该无参数的构造函数.

Either way, remove that no-parameter constructor.

这篇关于在Entity Framework Core中从cookie和基本路径创建数据库上下文的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆