EiE*_*Guy 6 c# entity-framework-core asp.net-core-mvc asp.net-core asp.net-core-middleware
我正在构建一个 ASP.Net Core API,但我无法找到从 DBContextOptions 获取连接字符串的方法。
我的startup.cs中有DBContext,如下所示;
public void ConfigureServices(IServiceCollection services)
{
// Add framework services.
services.AddApplicationInsightsTelemetry(Configuration);
services.AddEntityFrameworkSqlServer()
.AddDbContext<MainContext>(options => options.UseSqlServer(Configuration.GetConnectionString("MainConnection")));
services.AddMvc()
.AddJsonOptions(opt =>
{
opt.SerializerSettings.ContractResolver = new CamelCasePropertyNamesContractResolver();
});
}
Run Code Online (Sandbox Code Playgroud)
在我的 Context 类中,我有以下构造函数;
public MainContext(DbContextOptions<MainContext> options) : base(options)
{
}
Run Code Online (Sandbox Code Playgroud)
但除非我在 DBContext 类的 OnConfiguring 方法中添加一个实际的连接字符串,否则它不起作用,如下所示;
protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
{
//TODO Move connection string to a secure location
optionsBuilder.UseSqlServer(@"Server= .....");
}
Run Code Online (Sandbox Code Playgroud)
当我调试并检查 Configuration.GetConnectionString("MainConnection") 中的值时,我可以看到 Startup.cs 正在从 appsettings.json 文件中获取正确的连接字符串。
我认为通过 DI 将选项传递到 DbContext 类会传递连接字符串,但 DbContect 类不起作用,除非我在 OnConfiguring 方法中有那个 optionBuilder.UseSqlServer() 。
我发现这篇文章/sf/ask/2347281961/,它谈到使用以下代码从 options 属性中提取连接字符串
public ResourceDbContext(DbContextOptions options) : base(options)
{
_connectionString = ((SqlServerOptionsExtension)options.Extensions.First()).ConnectionString;
}
protected override void OnConfiguring(DbContextOptionsBuilder options)
{
options.UseSqlServer(_connectionString);
}
Run Code Online (Sandbox Code Playgroud)
但是当我尝试使用它时,我发现options.Extensions中不再有First()方法
所以,我的第一个问题是...
为什么 DBContext 类不需要在 OnConfiguring 方法中添加连接字符串就不能工作
我的第二个问题是...
如果 OnCONfiguring 方法中需要连接字符串,我如何从 DbContextOptions 选项对象中获取它,而不必在 OnConfiguring 方法中显式提供它 --> optionsBuilder.UseSqlServer(@"Server= .....") ;
至少对于 EF Core 1.1,您需要使用FindExtension<SqlServerOptionsExtension>()
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Infrastructure.Internal;
namespace MyNamespace
{
public class MyContext : DbContext
{
public MyContext(DbContextOptions<MyContext> options) : base(options)
{
var sqlServerOptionsExtension =
options.FindExtension<SqlServerOptionsExtension>();
if(sqlServerOptionsExtension != null)
{
string connectionString = sqlServerOptionsExtension.ConnectionString;
}
}
}
}
Run Code Online (Sandbox Code Playgroud)
如果您opt.UseInMemoryDatabase()在您的中使用,则存在空检查Startup.cs
您将在您的内部appsettings.json创建以下内容:
{
"Database" : {
"ConnectionString" : "..."
}
}
Run Code Online (Sandbox Code Playgroud)
然后在你的内部ConfigureServices你会执行以下操作:
services.AddSingleton(_ => Configuration);
Run Code Online (Sandbox Code Playgroud)
这将基本上填充该IConfigurationRoot属性。您可以将其注入到任何地方,并可以通过执行以下操作来访问连接字符串:
private readonly IConfigurationRoot configuration;
private IDbConnection dbConnection { get; }
public Example(IConfigurationRoot configuration)
{
this.Configuration = configuration;
dbConnection = new SqlConnection(this.configuration.GetConnectionString("..."));
}
Run Code Online (Sandbox Code Playgroud)
我的结构有点奇怪,您实际上只需将其传递ConnectionString给另一个类或注入方法,但这为您演示了。但我相信 Entity Framework 7 有一个工厂可以直接接受连接字符串。希望这对您有所帮助。
在实体框架中,您的内部应该是这样的ConfigureServices:
services.AddSingleton<dbContext>(_ => new dbContext(Configuration.GetConnectionString("...")));
public class dbContext : DbContext
{
public dbContext(string dbConnection) : base(dbConnection)
{
}
}
Run Code Online (Sandbox Code Playgroud)
一些额外的文档。
| 归档时间: |
|
| 查看次数: |
16038 次 |
| 最近记录: |