Entity Framework Core 1.0 Connection Strings

纵然是瞬间 提交于 2019-12-05 00:20:51

EF Core is intended to be configured via dependency injection. Dependency injection keeps your DbContext clean, and independent of implementation details of the environment.

Your initial solution of hard-coding connection strings tightly coupled the DbContext to the knowledge of where the database is located. That's obviously a problem. But your proposed solution tightly couples the DbContext to the knowledge of a particular configuration file. That, too, is a problem.

To keep the DbContext independent of environmental details, create a constructor that takes a DbContextOptions parameter and calls the base class constructor.

public class MyContext : DbContext
{
    public MyContext(DbContextOptions options) :
        base(options)
    {
    }
}

Do this instead of overriding OnConfiguring. Then initialize it in the Startup.cs of your host application. That's where the knowledge of the configuration file belongs.

public class Startup
{
    private IConfigurationRoot _configuration;

    public Startup(IHostingEnvironment env)
    {
        _configuration = new ConfigurationBuilder()
            .SetBasePath(env.ContentRootPath)
            .AddJsonFile("appsettings.json")
            .Build();
    }

    public void ConfigureServices(IServiceCollection services)
    {
        services.AddSingleton<IConfigurationRoot>(_configuration);

        services.AddDbContext<MyContext>(options => options
            .UseSqlServer(_configuration.GetConnectionString("MyContext")));
    }
}

Now you can use your DbContext from anywhere.

Jason Martin

ANSWER: I was making this much more difficult then it actually was. I followed Juunas' advise and added in the following code in my Repository DbContext Class:

protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder) 
{

  // get the configuration from the app settings
  var config = new ConfigurationBuilder()
        .SetBasePath(Directory.GetCurrentDirectory())
        .AddJsonFile("appsettings.json")
        .Build();

  // define the database to use
  optionsBuilder.UseSqlServer(config.GetConnectionString("StandardDatabase"));

}

Which works perfect with the dotnet ef command line tools and far as the multiple environment setup goes with my MVC UI sticking with the following default code in my startup.cs works great as well.

var builder = new ConfigurationBuilder()
      .SetBasePath(env.ContentRootPath)
      .AddJsonFile("appsettings.json", optional: true, reloadOnChange: true)
      .AddJsonFile($"appsettings.{env.EnvironmentName}.json", optional: true)
      .AddJsonFile("project.json", optional: true, reloadOnChange: true);

IDbContextFactory might also help. EF Command Line Tools and DI can use this factory to create instances of your DBContext. Design Time services (e.g. Migrations) will discover implementations of this interface that are in the same assembly as the derived context.

using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Infrastructure;

namespace MyProject
{
    public class BloggingContextFactory : IDbContextFactory<BloggingContext>
    {
        public BloggingContext Create()
        {
            var optionsBuilder = new DbContextOptionsBuilder<BloggingContext>();
            optionsBuilder.UseSqlite("Filename=./blog.db");

            return new BloggingContext(optionsBuilder.Options);
        }
    }
}
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!