项目的结构如下所示:
-
汽车(ASP.NET 核心MVC。这里我们有一个连接字符串(
-
Cars.Persistence (ASP.NET Core Class library.这里有存储库,数据库优先(
我通过此 msdn 文档中的以下命令创建了一个模型:
Scaffold-DbContext "Server=PCSQL2014XP;Database=Cars;Trusted_Connection=True;"
Microsoft.EntityFrameworkCore.SqlServer -OutputDir Models
目前为止,一切都好。但是,现在carsContext
在Cars.Persistence
- ASP.NET 核心类库中具有硬编码的连接字符串:
public partial class carsContext: DbContext
{
public carsContext()
{
}
public carsContext(DbContextOptions<carsContext> options)
: base(options)
{
}
public virtual DbSet<Cars> Cars { get; set; }
protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
{
if (!optionsBuilder.IsConfigured)
{
optionsBuilder.UseSqlServer("Server=PCSQL2014XP...");// hard coded
// connection string
}
}
}
起初,我想在我的类库中创建自己的appsettings.json
Cars.Persistence
。但是,根据这篇文章,不建议在类库中appsettings.json
文件
。我已经阅读了这种方法,但是,如果我再次运行此命令,硬编码字符串将再次出现:
Scaffold-DbContext "Server=PCSQL2014XP;Database=Cars;Trusted_Connection=True;"
Microsoft.EntityFrameworkCore.SqlServer -OutputDir Models
所以我的问题是如何在我的类库Cars.Persistence
中使用连接字符串(位于Cars
项目中(?
更新:
我已经注释掉了以下代码:
public partial class eshopContext : DbContext
{
public eshopContext(DbContextOptions<eshopContext> options): base(options)
{}
// public eshopContext(){}
/*protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
{
if (!optionsBuilder.IsConfigured)
{
#warning To protect potentially sensitive information in your connection string, you should move it out of source code. See http://go.microsoft.com/fwlink/?LinkId=723263 for guidance on storing connection strings.
optionsBuilder.UseSqlServer("Server=...");
}
}*/
}
你可以利用 .Net Core 依赖关系注入和开箱即用的功能。连接字符串将保留在 Web 项目中,但可以使用数据库上下文,而无需在类库项目中声明任何连接字符串。我正在共享现有项目中的代码示例。
设置连接字符串
您已在启动中引用了连接字符串并已添加到服务中。无需再次定义连接字符串,也无需使用内置 DI 使用数据库上下文。代码可能看起来像这样!
启动类
设置您的 SQL 配置。仔细查看 MigrationsAssembly,这是引用类库项目的位置。
public static IServiceCollection AddCustomDbContext(this IServiceCollection services, IConfiguration configuration)
{
// Add DbContext using SQL Server Provider
services.AddDbContext<PaymentDbContext>(options =>
options.UseSqlServer(configuration.GetConnectionString("myconnectionstring"), x => x.MigrationsAssembly("Payment.Persistence")));
return services;
}
上下文类
此类位于类库项目中。
public class PaymentDbContext : DbContext
{
public PaymentDbContext(DbContextOptions<PaymentDbContext> options)
: base(options)
{
}
public DbSet<Payments> Payments { get; set; }
}
使用 DI 访问上下文
private readonly PaymentDbContext _context;
public PaymentsRepository(PaymentDbContext dbContext)
{
_context = dbContext;
}
您可以在位于launchSettings.json
的Cars MVC项目中使用Environment Variable
。类似"MSSQL_CONN_STR": "Server=PC2014XP.."
然后在Cars.Persistence
类库中,您可以像这样访问环境变量
protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
{
if (!optionsBuilder.IsConfigured)
{
optionsBuilder.UseSqlServer(Environment.GetEnvironmentVariable("MSSQL_CONN_STR");
}
}
以下是我如何从netcoreapp2.2
中读取连接字符串。你可以在这里看到我是如何配置
的我创建 1 个文件名 appsetting.json 有这样的结构
"WebJobSettings": {
"DBConnectionString": "Data Source=.;Initial Catalog=CMSCore;Integrated Security=True"
},
然后在我的程序中.cs
public static class Program
{
public static IConfigurationRoot Configuration;
public static void Main()
{
var serviceCollection = new ServiceCollection();
ConfigureServices(serviceCollection);
// create service provider
var serviceProvider = serviceCollection.BuildServiceProvider();
// entry to run app
//serviceProvider.GetService<WebJob>().Run();
serviceProvider.GetService<WebJob>().RunImageProcessQueue();
}
private static void ConfigureServices(IServiceCollection serviceCollection)
{
var currentDir = Directory.GetCurrentDirectory();
// build configuration
var configuration = new ConfigurationBuilder()
.SetBasePath(currentDir)
.AddJsonFile("appsettings.json", false)
.Build();
serviceCollection.AddOptions();
serviceCollection.Configure<WebJobSettings>(configuration.GetSection("WebJobSettings"));
serviceCollection.Configure<QueueSettings>(configuration.GetSection("QueueSettings"));
serviceCollection.Configure<AssetSettings>(configuration.GetSection("AssetSettings"));
// add app
serviceCollection.AddTransient<WebJob>();
}
然后只是在我的 WebJob.cs 文件中配置模式,如下所示
public class WebJob
{
private readonly IOptions<WebJobSettings> _webJobSettings;
private readonly IOptions<QueueSettings> _queueSettings;
private readonly IOptions<AssetSettings> _assetSettings;
public WebJob(
IOptions<WebJobSettings> webJobSettings,
IOptions<QueueSettings> queueSettings,
IOptions<AssetSettings> assetSettings)
{
_webJobSettings = webJobSettings;
_queueSettings = queueSettings;
_assetSettings = assetSettings;
}
从本期开始,在脚手架DbContext时添加的连接字符串是默认设置。如果不想显示如此长且丑陋的连接字符串,可以改用命名连接字符串。
从这个讨论中,你可以在Scaffold-DbContext
命令中使用-Connection name
来获取在Web应用程序appsetting.json
Scaffold-DbContext -Connection name=DefaultConnection Microsoft.EntityFrameworkCore.SqlServer -OutputDir DbModels
"ConnectionStrings": {
"DefaultConnection": "Data Source=(localdb)\MSSQLLocalDB;Initial Catalog=MVC2_2Db;Integrated Security=True;Connect Timeout=30;Encrypt=False;TrustServerCertificate=False;ApplicationIntent=ReadWrite;MultiSubnetFailover=False"
},
上面的代码将在 DbContext 中生成以下代码
protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
{
if (!optionsBuilder.IsConfigured)
{
optionsBuilder.UseSqlServer("name=DefaultConnection");
}
}
或者,如果你设置了外部连接字符串,你可以删除硬编码的连接字符串,因为只有当你忘记设置数据库的连接时才会调用它。您可以参考在启动中添加的代码.cs如下所示:
var connection = @"Server=(localdb)mssqllocaldb;Database=MVC2_2Db;Trusted_Connection=True;ConnectRetryCount=0";
services.AddDbContext<Cars.Persistence.DbModels.MVC2_2DbContext>(options => options.UseSqlServer(connection));