2016-10-24 3 views
10

Я разрабатываю простое веб-приложение, и в будущем я хочу сделать это как многопользовательскую..NET Core получить строку подключения из appsettings.json

Так что я хочу, чтобы написать строку соединения прямо в OnConfiguring метод: класс

public class ApplicationContext : DbContext 
{ 
    public DbSet<User> Users { get; set; } 

    protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder) 
    { 
     optionsBuilder.UseSqlServer("connection string from appsettings.json"); 
     base.OnConfiguring(optionsBuilder); 
    } 
} 

Startup:

public void ConfigureServices(IServiceCollection services) 
{ 
    services.AddDbContext<ApplicationContext>(); 
    services.AddMvc(); 
} 

Как я могу извлечь строку подключения из appsettings.json в ApplicationContext класса?

Я не хотел бы создавать конструкторы для класса ApplicationContext.

+0

Вам нужно передать строку соединения в качестве параметра AddDbContext IIRC –

+0

Почему вы хотите зарегистрировать его в 'OnConfiguring' метод а не внутри 'services.AddDbContext (options => options.UseSqlServer (" ... "))'? – Tseng

+0

@Tseng Мне нужно изменить динамические строки подключения в будущем для многопользовательской аренды. –

ответ

5

Так что я хочу, чтобы написать строку соединения прямо в методе OnConfiguring:

Как может Я извлекаю строку подключения из appsettings.json в класс ApplicationContext?

Я бы не хотел создавать какие-либо конструкторы для класса ApplicationContext.

Вы можете использовать Options Pattern через IOptions но самый простой способ это использование DI в ApplicationContext конструктору;)

Следуйте ниже статей, пожалуйста:

8

Давайте представим, что у вас есть .NET Core, приложение и файл appsettings.json выглядит следующим образом:

{ 
    "Logging": { 
    "IncludeScopes": false, 
    "LogLevel": { 
     "Default": "Debug", 
     "System": "Information", 
     "Microsoft": "Information" 
    } 
    }, 
    "Production": { 
    "SqliteConnectionString": "Filename=./MyDatabase.sqlite" 
    } 
} 

Вы можете получить SqliteConnectionString значение из Startup.cs так:

public void ConfigureServices(IServiceCollection services) 
{ 
    var connection = Configuration["Production:SqliteConnectionString"]; 

    services.AddDbContext<MyContext>(options => 
     options.UseSqlite(connection) 
    ); 
    .... 
} 

, а затем в ваш DBContext вы должны добавить конструктор, который принимает DbContextOptions:

public class MyContext : DbContext 
{ 
    public MyContext (DbContextOptions<MyContext> options) : base(options) 
    { } 

    ... 
} 
+0

Это хорошо. Но как я могу получить одну и ту же строку в классе ApplicationContext? Я не могу сделать это, как вы писали. –

+3

А что, если я хочу использовать безпараметрический конструктор для 'MyContext'? –

0

Вы можете использовать заводскую узору, чтобы разрешить DbContext.

public interface ITenantDbContextFactory 
{ 
    ApplicationContext Create(string tenantId); 
} 

public class TenantDbContextFactory() 
{ 
    private ApplicationContext context; 

    public TenantDbContextFactory() 
    { 
    } 

    public ApplicationContext Create(string tenantId) 
    { 
     if(this.context==null) 
     { 
      var connectionString = GetConnectionForTenant(tenantId); 
      var dbContextBuilder = new DbContextOptionsBuilder(); 
      dbContextBuilder.UseSqlServer(connectionString); 

      this.context = new ApplicationContext(dbContextBuilder); 
     } 

     return this.context; 
    } 
} 

В Startup:

services.AddDbContext<ApplicationContext>(); 
services.AddScoped<ITenantDbContextFactory, TenantDbContextFactory>(); 

Ваш сервис или контроллер:

public class HomeController 
{ 
    private readonly ITenantDbContextFactory dbFactory; 
    public HomeControler(ITenantDbContextFactory tenantDbContextFactory) 
    { 
     this.dbFactory = tenantDbContextFactory; 
    } 

    public void Action() 
    { 
     var dbContext = this.dbFactory.Create("tenantA"); 
     // use your context here 
     dbContext... 
    } 
} 
0

Я использую .NET Core 1.1.И это, как я решил эту проблему:

Добавить строка подключения к appsettings.json:

{ 
    "Logging": { 
    "IncludeScopes": false, 
    "LogLevel": { 
     "Default": "Warning" 
    } 
    }, 
    "ConnectionStrings": { 
    "MyConnectionString": "Data Source=yourIp,1433;Initial Catalog=yourCatalog;Integrated Security=True;User Id=yourUser;Password=yourPassword;MultipleActiveResultSets=True" 
    } 
} 

Затем я создал статический класс для доступа к ConnectionString собственности от «где угодно»:

namespace MyProject.Orm 
{ 
    public static class DatabaseConnection 
    { 
     public static string ConnectionString { get; set; } 

     public static SqlConnection ConnectionFactory() 
     { 
      return new SqlConnection(ConnectionString); 
     } 
    } 
} 

Я также должен был добавить этот пакет NuGet: System.Data.SqlClient

И затем я установил ConnectionString собственность у в Startup.cs:

public void ConfigureServices(IServiceCollection services) 
     { 
      // Add framework services. 
      services.AddMvc(); 

      Orm.DatabaseConnection.ConnectionString = Configuration["ConnectionStrings:MyConnectionString"]; 
     } 

И тогда вы можете получить доступ к строке подключения через: MyProject.Orm.ConnectionString

+1

Я использовал это для этой же проблемы в приложении .NET Core 2, и это прекрасно. Настоятельно рекомендую. – Matt