从 Entity Framework Core 中的 cookie 和基本路径创建数据库上下文

Create database context from cookie and base path in Entity Framework Core

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

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

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

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

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

家庭控制器尝试使用它:

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

这会引发异常,因为工厂成员为空。如何解决这个问题?

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。

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

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 注入您的控制器。

无论哪种方式,删除无参数构造函数。