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

查看:26
本文介绍了在 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 Core Data 提供程序.

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();
    ....

这会抛出异常,因为工厂成员为空.如何解决这个问题?

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天全站免登陆