Как я могу реализовать строку соединения 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;",
}
}