2016-12-14 6 views
2

ASP.NET Core 1.1 응용 프로그램을 사용 중이고 구성 파일에서 연결 문자열을 읽으려고합니다.구성 파일 (appsettings.json)에서 읽는 데이터베이스 컨텍스트에 대한 ASP.NET 코어 실행 마이그레이션

내 데이터베이스 컨텍스트 클래스는 다음과 같습니다

public class ApplicationDbContext : DbContext, IDbContextFactory<ApplicationDbContext> 
{ 
    public ApplicationDbContext() 
    { 
    } 

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

    protected override void OnModelCreating(ModelBuilder builder) 
    { 
     base.OnModelCreating(builder); 
    } 

    public ApplicationDbContext Create(DbContextFactoryOptions options) 
    { 
     var builder = new DbContextOptionsBuilder<ApplicationDbContext>(); 

     string connString = "some hardcoded connection string"; 
     builder.UseSqlServer(connString); 
     return new ApplicationDbContext(builder.Options); 
    } 
} 

실행 마이그레이션이 미세 (예를 들어, dotnet ef database update) 작동합니다. 내가 찾을 수없는 무언가를 주입하지 않고 내가 ApplicationDbContextIConfiguration를 삽입하려고하면

  • 은 마이그레이션이 No parameterless constructor defined for this object.
  • 실패합니다 :

    내가 하드 코드 된 연결 문자열을 제거하려면

    , 나는 다음과 같은 문제에 직면하고있다 구성 파일에서 정보를 읽는 방법

어떻게 진행해야합니까?

감사합니다.

[편집] Startup.cs에서

내가 연결 문자열을 구성한하고 (런타임)가 제대로 작동합니다

public void ConfigureServices(IServiceCollection services) 
{ 
    // Add framework services. 
    //services.AddApplicationInsightsTelemetry(Configuration); 

    string connString = ConfigurationExtensions.GetConnectionString(Configuration, "DefaultConnection"); 
    services.AddDbContext<ApplicationDbContext>(options => options.UseSqlServer(connString)); 

    services.AddMvc(); 
} 

문제는 dotnet migrations 데이터베이스 컨텍스트에서 매개 변수가없는 생성자를 요구하는 것이다 IDbContextFactory<>을 구현하고 구성을 주입하는 방법을 모르겠습니다.

편집 ApplicationDbContext 내가 제안 솔루션을 시도

와 iOptions에 <>을 시도,하지만 난 dotnet migration 기본 생성자를 호출하기 때문에 작동 할 수 없습니다 후.

public class ApplicationDbContext : DbContext, IDbContextFactory<ApplicationDbContext> 
{ 
    private IOptions<DefaultConnectionValue> ConnOptions; 
    private string connectionString; 

    public ApplicationDbContext() 
    { 
     Console.WriteLine("Default constructor was called"); 
    } 

    public ApplicationDbContext(DbContextOptions<ApplicationDbContext> options, IOptions<DefaultConnectionValue> connOptions) : base(options) 
    { 
     ConnOptions = connOptions; 
     connectionString = connOptions.Value.Value; 

     Console.WriteLine($"Injected connection string = {connectionString}"); 
    } 

    protected override void OnModelCreating(ModelBuilder builder) 
    { 
     base.OnModelCreating(builder); 
    } 

    public ApplicationDbContext Create(DbContextFactoryOptions options) 
    { 
     var builder = new DbContextOptionsBuilder<ApplicationDbContext>(); 

     //string connString = ConfigurationExtensions.GetConnectionString(null, "DefaultConnection"); 
     builder.UseSqlServer(connectionString); 
     return new ApplicationDbContext(builder.Options, ConnOptions); 
    } 
+0

을하지만 ConfigureServices에 추가 않았다 services.AddDbContext를 (옵션 => options.UseSqlServer (Configuration.GetConnectionString ("DefaultConnection"))); https://docs.microsoft.com/en-us/aspnet/core/data/ef-mvc/intro – Alexan

+0

@Alex - 질문에 대한 답변을 편집했습니다. – Alexei

답변

2

저도 같은 문제에 직면하고 나는 다음과 같은 방법으로 해결 :

  • 를 주입 옵션 DBContext
  • 사용자 연결에 서비스 컬렉션의 연결 문자열을

    1. 등록 옵션을 DBContext 매개 변수가없는 생성자의 문자열

    덕분에 마이그레이션에 필요한 매개 변수없는 생성자가 있어야합니다.

    public class Startup 
    { 
        public Startup(IHostingEnvironment env) 
        { 
         // Set up configuration sources. 
         var builder = new ConfigurationBuilder() 
          .SetBasePath(env.ContentRootPath) 
          .AddJsonFile("appsettings.json", optional: true, reloadOnChange: true); //let's assume that here you have your connection string 
    
         Configuration = builder.Build(); 
        } 
    
        public IConfigurationRoot Configuration { get; set; } 
    
        public void ConfigureServices(IServiceCollection services) 
        { 
         // Adds services required for using options. 
         services.AddOptions(); 
    
         // Register the IConfiguration instance which MyOptions binds against. 
         services.Configure<MyOptions>(Configuration); 
    
         ... 
        } 
    } 
    

    을 그리고 당신이 같은 경작 사용할 수 있습니다 (이 컨트롤러 예입니다하지만 당신은 DBContext과 같은 작업을 수행 할 수 있습니다) : 여기

    는 구성 설정을 등록 할 수있는 방법입니다

    public class HomeController : Controller 
    { 
        private readonly MyOptions _optionsAccessor; 
    
        public HomeController(IOptions<MyOptions> optionsAccessor) 
        { 
         //injection of your configuration object with connection string 
         _optionsAccessor = optionsAccessor.Value; 
        } 
    
        public IActionResult Index() 
        { 
         var option1 = _optionsAccessor.Option1; 
         var option2 = _optionsAccessor.Option2; 
         return Content($"option1 = {option1}, option2 = {option2}"); 
        } 
    } 
    

    구성 설정 사용에 대한 자세한 내용은 여기를 참조하십시오 : Configuration.

    업데이트 : 당신은 또한 다른 접근 방법을 시도 할 수 있습니다

    - DBContext 생성자의 내부 구성을 읽을 :

    public class ApplicationDbContext : DbContext, IDbContextFactory<ApplicationDbContext> 
    { 
        private string connectionString; 
    
        public ApplicationDbContext() 
        { 
         var builder = new ConfigurationBuilder().AddJsonFile("appsettings.json", optional: true, reloadOnChange: true); //let's assume that here you have your connection string 
         var configuration = builder.Build(); 
    
         connectionString = ""; //FILL THE CONNECTION STRING FROM THE CONFIGURATION OBJECT 
        } 
    
        ... 
    } 
    
  • +0

    제안 된 솔루션을 시도했지만 데이터베이스 컨텍스트의 옵션을 주입하는 데 여전히 어려움이 있습니다. 'dotnet migrations'는 기본 생성자만을 호출하고 아무것도 삽입 할 수 없습니다. 나는 그 질문을 편집했다. 감사. – Alexei

    +0

    그것은 작동합니다. 그러나, 나는'appsettings.json'에 대한 경로를 얻는 적절한 방법을 찾아야합니다. 현재'full_path_to_appname \ bin \ Debug \ netcoreapp1.1 \ win7-x64'를 반환하는'AppContext.BaseDirectory'를 사용하고 있으며'\ bin'으로 시작하는 모든 것을 제거하고 있습니다. – Alexei