EFCore和.net Core2.0中与DbContext的多重连接

时间:2018-10-27 05:36:08

标签: asp.net-core-webapi dbcontext ef-core-2.0

使用多重连接连接到DBcontext时遇到了问题。请帮我解决这个问题,这是我的情况。

  1. 我有一个Angular5应用程序和Webapi控制器。我有4个数据库,每个数据库都有不同的用户。

  2. 当4个用户尝试通过Webapi控制器同时连接到其数据库时,此时所有用户都从单个数据库获取数据(而不是获取其他数据库)。

  3. 当我们尝试一一连接时,数据将正确获取。

这是我用于动态连接的示例代码。

上下文连接字符串:

 protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
    {
         #warning To protect potentially sensitive information in your connection string, you should move it out of source code. See http://go.microsoft.com/fwlink/?LinkId=723263 for guidance on storing connection strings.
          optionsBuilder.UseSqlServer(LoginController.ConnectionString);

    }

Controler API:

public IEnumerable<object> Getvendordetails([FromBody] dynamic id)
    {
        if (Request != null)
        {
            LoginController.DynamicDbname = Request.Headers["Connectionstring"];
        }
        ContextEntity obj = new ContextEntity();
    }

此处 LoginController.DynamicDbname 是静态变量。

编辑代码:

控制器:

    namespace AngularDotnetCore.Controllers
   {
     [Route("api/[controller]")]
    public class HomeController : Controller
    {
       private readonly IHttpContextAccessor httpContext;
       private ContextEntity db;
      public HomeController(IHttpContextAccessor _httpContext)
    {

        this.httpContext = _httpContext;
        db = new ContextEntity(httpContext);

    }
    [HttpPost("GetVendors")]
    public IEnumerable<object> Getvendordetails([FromBody] dynamic id)
    {
        //string DynamicConnection = Request.Headers["Connection"];
        db = new ContextEntity(httpContext);
        return db.Vendors;
    }

    [HttpGet("GetItems")]
    public IEnumerable<object> GetItems()
    {
        //string DynamicConnection = Request.Headers["Connection"];
        db = new ContextEntity(httpContext);
        return db.Items;
    }

}

}

DBContext:

   private readonly HttpContext httpContext;
  public ContextEntity(IHttpContextAccessor httpContextAccessor)
    : base()
    {
        httpContext = httpContextAccessor.HttpContext;
    }
     protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
   {
       var connection = httpContext.Request.Headers["Connection"];
      optionsBuilder.UseSqlServer(connection);

   }

对于每个API请求,我已经将httpcontext参数传递给Dbcontext基类。

请在这个问题上帮助我,如果我的代码错误,请以很好的方式建议我。

谢谢 维克多·A

2 个答案:

答案 0 :(得分:1)

如果LoginController.DynamicDbName是静态变量,则它将在所有请求之间共享。这意味着您的API在每个请求上都覆盖了该值,并且所有用户都在使用最后一个来创建dbconnection。将其设置为非静态,并为每个请求创建登录控制台的新实例,并将其注入到所有相关服务(如DbContext)中。这样您的问题就会消失。

如果您正在使用从命令行进行的迁移,则可能需要将EF Core版本升级到2.1(或2.2,我无法确定),因为2.0在将非标准的类/接口注入到Context时存在一些问题

答案 1 :(得分:1)

要从DbContext访问http标头,可以尝试IHttpContextAccessor,而无需引用LoginContoller

    public class ApplicationDbContext : IdentityDbContext<ApplicationUser>
{
    private readonly HttpContext httpContext;
    public ApplicationDbContext(DbContextOptions<ApplicationDbContext> options, IHttpContextAccessor httpContextAccessor)
        : base(options)
    {
        httpContext = httpContextAccessor.HttpContext;
    }
    protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
    {
        var connection = httpContext.Request.Headers["Connectionstring"];
        optionsBuilder.UseSqlServer(connection);
    }       
}

编辑:您似乎在控制器中初始化了ContextEntity而不是使用DI,如果这样,请尝试直接传递连接字符串而不是IHttpContextAccessor

namespace AngularDotnetCore.Controllers
   {
 [Route("api/[controller]")]
public class HomeController : Controller
{      
   private ContextEntity db;
  public HomeController()
{

    var connection = Request.Headers["Connection"];
    db = new ContextEntity(connection);

}
  }

DbContext

private readonly string _connection;
  public ContextEntity(string connection)
: base()
{
    _connection = connection;
}
 protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
   {
  optionsBuilder.UseSqlServer(_connection);

    }