【问题标题】:.NET Core get connection string from appsettings.json.NET Core 从 appsettings.json 获取连接字符串
【发布时间】:2016-10-24 12:47:31
【问题描述】:

我开发了一个简单的网络应用程序,并且在未来,我想将它作为多租户来实现。

所以我想将连接字符串直接写入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);
    }
}

启动类:

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

如何将连接字符串从appsettings.json 提取到ApplicationContext 类中?

我不想为ApplicationContext 类创建任何构造函数。

【问题讨论】:

  • 您需要将连接字符串作为参数传递给 AddDbContext IIRC
  • 为什么要将其注册到OnConfiguring 方法而不是services.AddDbContext&lt;ApplicationContext&gt;(options =&gt; options.UseSqlServer("...")) 内?
  • @Tseng 我以后需要动态更改连接字符串以实现多租户。
  • @A.Gladkiy 您要动态更改正在使用的上下文的连接字符串吗?听起来是个坏主意。为什么不多次注册上下文?
  • @CamiloTerevinto 我想在用户注册后每次创建数据库。多次注册上下文是什么意思?

标签: c# asp.net-core .net-core


【解决方案1】:

假设您有 .NET Core 应用程序,并且您的 appsettings.json 文件如下所示:

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

您可以像这样从Startup.cs 获取SqliteConnectionString 值:

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)
    { }

    ...
}

【讨论】:

  • 很好。但是我怎样才能将相同的字符串放入ApplicationContext 类?我不能像你写的那样做。
  • 如果我想为MyContext 使用无参数构造函数怎么办?
【解决方案2】:

.NET Core 2.0

添加这个类:

// Requires NuGet package Microsoft.Extensions.Configuration.Json

using Microsoft.Extensions.Configuration;
using System.IO;

namespace RutarBackgroundServices.AppsettingsJson
{
    public static class AppSettingsJson
    {
        public static string ApplicationExeDirectory()
        {
            var location = System.Reflection.Assembly.GetExecutingAssembly().Location;
            var appRoot = Path.GetDirectoryName(location);

            return appRoot;
        }

        public static IConfigurationRoot GetAppSettings()
        {
            string applicationExeDirectory = ApplicationExeDirectory();

            var builder = new ConfigurationBuilder()
            .SetBasePath(applicationExeDirectory)
            .AddJsonFile("appsettings.json");

            return builder.Build();
        }


    }
}

从“appsettings.json”文件中获取键“MssqlConnectionString”的值:

var appSettingsJson = AppSettingsJson.GetAppSettings();
var connectionString = appSettingsJson["MssqlConnectionString"];

在你的项目根目录下创建文件“appsettings.json”:

{
  "MssqlConnectionString": "Server=yourip; Database=yourdbname; User Id=yourusername; Password=yourpassword; Pooling=true;",
  "Db2ConnectionString": "Database=yourdbname;UserID=yourusername;Password=yourpassword;Server=yourip:yourport",
  "SomeOtherKey": "SomeOtherValue"
}

【讨论】:

  • 我在 .NET Core 2 应用程序中使用它来解决同样的问题,它非常完美。强烈推荐。
  • 最好使用“ConnectionStrings”部分,如:{“ConnectionStrings”:{“MssqlConnectionString”:“Server=yourip;Database=yourdbname;User Id=yourusername;Password=yourpassword;Pooling=true ;", "Db2ConnectionString": "Database=yourdbname;UserID=yourusername;Password=yourpassword;Server=yourip:yourport", }, "SomeOtherKey": "SomeOtherValue"}
【解决方案3】:

所以我想将连接字符串直接写入 OnConfiguring 方法:

如何将 appsettings.json 中的连接字符串提取到 ApplicationContext 类中?

我不想为 ApplicationContext 类创建任何构造函数。

您可以通过IOptions 使用选项模式,但最简单的方法是在ApplicationContext 构造函数中使用DI ;)

请关注以下文章:

【讨论】:

    【解决方案4】:

    您可以使用工厂模式来解析您的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;
        }
    }
    

    在启动中:

    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...
        }
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-06-20
      • 2023-03-18
      • 1970-01-01
      • 2016-10-02
      相关资源
      最近更新 更多