从appsettings.json获取.NET Core连接字符串

25

我正在开发一个简单的 Web 应用程序,并且将来希望将其作为多租户应用程序实现。

因此,我想直接将连接字符串编写到 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,如果我没记错的话。 - Camilo Terevinto
为什么你想要在 OnConfiguring 方法中注册它,而不是在 services.AddDbContext<ApplicationContext>(options => options.UseSqlServer("...")) 中注册? - Tseng
@Tseng,我需要为多租户将来动态更改连接字符串。 - A. Gladkiy
@A.Gladkiy 你打算动态更改正在使用的上下文的连接字符串吗?听起来不是一个好主意。为什么不直接多次注册上下文呢? - Camilo Terevinto
@CamiloTerevinto 我想在用户注册后每次创建数据库。您所说的多次注册上下文是什么意思? - A. Gladkiy
@CamiloTerevinto 我不确定它会是什么样子,但如果你能给我一个好的多租户+ .Net Core实现的链接,我会很高兴的。 - A. Gladkiy
4个回答

23

让我们假设您拥有一个 .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)
    { }

    ...
}

2
很好。但是我如何将相同的字符串获取到ApplicationContext类中呢?我不能像你写的那样做。 - A. Gladkiy
3
如果我想要使用 MyContext 的无参构造函数,应该怎么做? - A. Gladkiy

11

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

2
我在.NET Core 2应用程序中遇到了同样的问题,使用了这个方法后完美解决。强烈推荐。 - Matt
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"} - Daniel Corbett

4
我希望直接在OnConfiguring方法中编写连接字符串:如何从appsettings.json中提取连接字符串到ApplicationContext类中?我不想为ApplicationContext类创建任何构造函数。
你可以通过IOptions使用选项模式,但最简单的方法是在ApplicationContext构造函数中使用DI ;)
请参考以下文章:
- 使用IOptions的示例, - 使用选项和配置对象, - IOptions接口

2
你可以使用工厂模式来解决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...
    }
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接