Как я могу реализовать строку соединения DbContext в .NET Core?

Моя ситуация очень похожа на эту ссылку или хотя бы мой код похож, и я пытаюсь найти способ применить этот же метод в синтаксисе .NET Core.

Пропустить строку подключения кодовому DbContext

Мой конкретный код выглядит следующим образом:

public partial class CompanyFormsContext : DbContext
{
    public CompanyFormsContext()
        : base("name=CompanyFormsContext")
    {
    }

    public CompanyFormsContext(string connName)
        : base("name=" + connName)
    {
    }
    ...
}

Я получаю сообщение об ошибке:

Ошибка CS1503 Аргумент 1: невозможно преобразовать из 'string' в 'Microsoft.EntityFrameworkCore.DbContextOptions' CompanyForms..NETCoreApp, Version = v1.0

когда я просматриваю скобки в base("name=CompanyFormsContext") или base("name=" = connName).

Каков правильный способ реализации этой функции в .NET Core?

Edit:

Я хотел поделиться тем, что у меня есть следующая информация для подключения к базе данных в моем файле appsettings.json: (Однако у меня нет настроек в startup.cs)

  "Data": {
    "CompanyFormsContext": {
      "ConnectionString": "Server=(localdb)\\projectsv13;Database=companyforms;Trusted_Connection=True;"
    },
    "CompanyFormsContextQA": {
      "ConnectionString": "Server=(localdb)\\projectsv13;Database=companyforms;Trusted_Connection=True;"
    }
  }

и я нашел следующую ссылку Добавление DbContextOptions в Startup.cs, не регистрирующую хранилище данных на веб-сайте, и мне интересно, достаточно ли простого protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder) исправить мое соединение или нет?

Из ссылки:

services.AddEntityFramework(Configuration)
    .AddSqlServer()
    .AddDbContext<MyDbContext>(
        options =>
        options.UseSqlServer(Configuration.Get("Data:CompanyFormsContext:ConnectionString"))
    );

Нужен ли мне такой сервис в моем Startup.cs?

Ответ 1

Другой вариант - вызвать базовый конструктор, который принимает DbContextOptions:

public BooksContext(string connectionString) : base(GetOptions(connectionString))
{
}

private static DbContextOptions GetOptions(string connectionString)
{
    return SqlServerDbContextOptionsExtensions.UseSqlServer(new DbContextOptionsBuilder(), connectionString).Options;
}

Ответ 2

Как правило, вы захотите прочитать его из config при запуске, а затем использовать строку подключения для настройки службы Entity Framework DbContext для вашего процесса.

1) Добавьте строку в свой appsettings.json:

"DbConnectionString": "Server=s;Database=db;Trusted_Connection=True;",

2) Прочитайте строку в классе Startup.cs(после вызова метода Startup для создания Конфигурации, как обычно, в методе ConfigureServices):

var connection = Configuration["DbConnectionString"];

3) Если использование Entity Framework добавляет службу контекста базы данных (MyDbContext - это класс контекста, созданный EF). Вы также хотите указать встроенную инъекцию зависимостей, как создать экземпляр контекста базы данных:

services.AddDbContext<MyDbContext>(options => options.UseSqlServer(connection));
services.AddScoped<IMyDbContext, MyDbContext>();

Где IMyDbContext (упрощенно), просто интерфейс, который вы извлекли из MyDbContext

4) Теперь вы можете определить свой контроллер для использования MyDbContext, и DI позаботится о его создании и передаче его при вызове контроллера:

public MyController(IMyDbContext context)
{
    _context = context  // store for later use
}

Ответ 3

Наилучшая практика ИМО:

добавить в конфигурацию .json:

     "ConnectionStrings": {
    "BooksContext": "Server=MyServer;Database=MyDb;Trusted_Connection=True;"
  }

и инициализировать раздел:

services.AddDbContext<BooksContext>(options => options.UseSqlServer(configuration.GetConnectionString(nameof(BooksContext))));

Ответ 4

Startup.cs для статического соединения

services.AddScoped<MyContext>(_ => new MyContext(Configuration.GetConnectionString("myDB")));

Table1Repository.cs для динамического соединения

using (var _context = new MyContext(@"server=....){
context.Table1....
}

MyContext.cs

public MyContext(string connectionString) : base(GetOptions(connectionString))
{
}

private static DbContextOptions GetOptions(string connectionString)
{
    return SqlServerDbContextOptionsExtensions.UseSqlServer(new DbContextOptionsBuilder(), connectionString).Options;
}

Ответ 5

Таким образом, я искал решение моей проблемы, которое было мне необходимо для динамического подключения к базе данных на основе данных, которых у меня нет, пока не будет времени для подключения. В основном, динамический контекст. У меня не было данных, передаваемых по URL, и у меня не было короткого списка возможных баз данных для присоединения). Итак, вот мое решение поставленной проблемы. Этот код позволит вам использовать файл appsettings.json для определения строки соединения с заполнителем, который будет заменен во время выполнения кодом. Это можно сделать в контроллере или другом классе, как вы считаете нужным.

Я использую как статический контекст, так и динамический контекст, но вы можете использовать только динамический.

Надеюсь, кто-нибудь наткнется на это и скажет, слава богу... хотя, вероятно, кто-то скажет, что этот парень идиот В любом случае, наслаждайтесь.

using System;
using System.Globalization;
using System.Linq;
using Microsoft.Extensions.Configuration;

namespace CallCenter.Repositories
{
    public class TestRepository : ITestRepository 
    {
        private readonly InsuranceContext _context;
        public TestRepository InsuranceContext context)
        {
            _context = context;
        }

        public void Add(string passedInStringWhichTellsWhatDatabaseToUse)
        {
            var builder = new ConfigurationBuilder().AddJsonFile("appsettings.json");

            var configuration = builder.Build();
            var connectionString = configuration.GetConnectionString("DefaultConnection");


                var agencyContext = new AgencyContext(connectionString.Replace("Database=replacethisstring", "Database=" + passedInStringWhichTellsWhatDatabaseToUse));

                var company = agencyContext.Companys.FirstOrDefault(x => x.ColumnNameInDb == "xyz");
                if (company != null)
                {
                    companyId = company.CompanyId.ToString();
                }

... your other code here which could include the using the passed in _context from the injected code (or you could not have any context passed in and just use dynamic context
            }

        }
    }
}

//The AgencyContext class would look like this:

using Microsoft.EntityFrameworkCore;

namespace CallCenter.Entities
{
    public class AgencyContext : DbContext
    {
        public AgencyContext(string connectionString) : base(GetOptions(connectionString))
        {

        }

        private static DbContextOptions GetOptions(string connectionString)
        {
            return SqlServerDbContextOptionsExtensions.UseSqlServer(new DbContextOptionsBuilder(), connectionString).Options;
        }

        public DbSet<Companys> Companys { get; set; }
    }
}

//The startup.c IServiceProvider module has this:

        public IServiceProvider ConfigureServices(IServiceCollection services)
        {
            services.AddOptions();

            services.AddDbContext<InsuranceContext>(options => options.UseSqlServer(Configuration.GetConnectionString("DefaultConnection"), b => b.UseRowNumberForPaging()));
            services.AddScoped<ITestRepository , TestRepository >();
....
}

И, наконец, файл appsettings.jason будет содержать это:

{
  "ConnectionStrings": {
    "DefaultConnection": "Server=yourservername;Database=replacethisstring;User ID=youruserid;Password=yourpassword;TrustServerCertificate=True;Trusted_Connection=False;Connection Timeout=30;Integrated Security=False;Persist Security Info=False;Encrypt=True;MultipleActiveResultSets=True;",
}
}