Многократное подключение к DbContext в EFCore и .net Core2.0 - PullRequest
0 голосов
/ 27 октября 2018

У меня возникла проблема с подключением к 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);

    }

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

   }

Я передал параметр httpcontext базовому классу Dbcontext для каждого запроса API.

Пожалуйста, помогите мне в этой проблеме, если мой код неверен, пожалуйста, предложите мне хороший способ.

Спасибо Victor.A

Ответы [ 2 ]

0 голосов
/ 29 октября 2018

Для доступа к заголовку http из DbContext, вы можете попробовать 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);

    }
0 голосов
/ 27 октября 2018

Если LoginController.DynamicDbName является статической переменной, она распределяется между всеми вашими запросами.Это означает, что ваш API переопределяет это значение при каждом запросе, и все пользователи используют последний для создания dbconnection.Сделайте его нестатичным и создайте новый экземпляр вашего контроллера входа в систему для каждого запроса и добавьте его во все связанные службы, такие как DbContext.Тогда ваша проблема исчезнет.

Если вы используете миграцию из командной строки, вам может потребоваться обновить версию EF Core до 2.1 (или 2.2, я не помню), потому что 2.0 имеет некоторые проблемы с введением не-стандартные классы / интерфейсы для вашего контекста

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...