简体   繁体   中英

How do I set the OnConfiguring method in my DbContext without any hardcoded connection string?

I'm using multiple examples on how to set up my MySql service but in almost every one (including the Microsoft), they are using a hard coded connection string.

This is my startup:

    services.AddDbContext<DbContext>(options =>
    {
        options.UseMySql(configuration.GetConnectionString("DefaultConnection"),
        mysqlOptions =>
        {
            mysqlOptions.ServerVersion(new ServerVersion(new Version(8, 0, 18)));
        });
    });

And whenever I try to Update-Database I see an error telling me that there's no password setted

MySql.Data.MySqlClient.MySqlException (0x80004005): Access denied for user 'root'@'localhost' (using password: YES).

After looking around a bit I found an overrideable method called OnConfiguring , but I want to set the connection string in a dynamic way, cause If I change my environment, I want that string to change too.

This is where I found almost every example with hardcoded strings (ex. https://dev.mysql.com/doc/connector-net/en/connector-net-entityframework-core.html )

You need to init configuration if not configured.

This can be done by overriding the OnConfiguring method in DbContext .

This way you can have global application configuration that will be pulled when application is ran. And use local configuration when doing Db migration.

Try this

public class YourContext: DbContext
{

    protected override void OnConfiguring(DbContextOptionsBuilder options)
    {
        if (options.IsConfigured == false)
            options.UseMysql({YOUR_CONNECTION_STRING});
    }
}

in configuration file, you should have a ConnectionStrings that points to your database with other options.

"ConnectionStrings": {
   "DefaultConnection": "server=127.0.0.1;uid=root;pwd=12345;database=test"
},

When you use configuration.GetConnectionString, you are looking up a value from the configuration section.

Try this at startup.cs

public class Startup
{
    private readonly IConfiguration _config;

    public Startup(IConfiguration config) 
    {
        _config = config;
    }

    // This method gets called by the runtime. Use this method to add services to the 
    container.
    public void ConfigureServices(IServiceCollection services)
    {
        services.AddDbContext<MainContext>(options => 
           options.UseOracle(_config["CONNECTION_STRING"]));
    }
 }

And do that at your Context ctor

public MainContext(DbContextOptions<MainContext> options) : base(options) { }

Based on the comment , I think you want to separate the EF Core related classes to a different assembly.

In the UseMySql there is an option to configure MigrationsAssembly . You can get more details here

Here is pseudo-code for SQL Server.

services.AddDbContext<EFCoreDemoContext>(options =>
{
    options.UseSqlServer(Configuration.GetConnectionString("DefaultConnection"),
            assembly => assembly.MigrationsAssembly(typeof(EFCoreDemoContext).Assembly.FullName));
});

I am addressing this portion of your question:

"After looking around a bit I found an overrideable method called OnConfiguring, but I want to set the connection string in a dynamic way, cause If I change my environment, I want that string to change too."

In order to solve getting the connection string into the OnConfiguring method inside your DbContext class I simply passed IConfiguration into the DbContext constructor like this.

    private readonly IConfiguration _config;

    public CoreDbContext(IConfiguration config)
    {
        _config = config;
    }

    public CoreDbContext(DbContextOptions<CoreDbContext> options, 
                         IConfiguration config) : base(options)
    {
        _config = config;
    }

Then in the OnConfiguring method I pulled the connection string from that config object injected at construction. Like this:

protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
    {
        if (!optionsBuilder.IsConfigured)
        {
            optionsBuilder.UseSqlServer(_config.GetConnectionString("YourKeyValueForConnStringInAppSettings.json"));
        }
    }

Finally here are details of my environment / Project:

  • Windows 10 machine
  • Visual Studio 2022 (Version 17.0.4)
  • ASP.NET Core Web API
  • .NET 6.0
  • Configure for HTTPS
  • Use controllers checked
  • Enable OpenApi support
  • Authentication type at time of writing is None

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM