简体   繁体   English

实体框架核心1.0连接字符串

[英]Entity Framework Core 1.0 Connection Strings

We are working on a vary large ASP.NET Core MVC 1.0 application. 我们正在开发一个不同的大型ASP.NET Core MVC 1.0应用程序。 We have 4-tiers to each of our applications as follows: 我们的每个应用程序有4层,如下所示:

  1. DTO DTO
  2. Repository (Entity Framework - Code First) 存储库(实体框架 - 代码优先)
  3. Service (Business Logic) 服务(业务逻辑)
  4. MVC (UI-MVC) MVC(UI-MVC)

Currently, in our repositories, which handle all database operations we have hard coded the database connection strings in the DbContext as follows: 目前,在处理所有数据库操作的存储库中,我们对DbContext中的数据库连接字符串进行了硬编码,如下所示:

protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder) {

    optionsBuilder.UseSqlServer("Data Source=somedatabase.database.windows.net;Initial Catalog=database;Integrated Security=False;User ID=username;Password=password;Connect Timeout=60;Encrypt=True;TrustServerCertificate=False;ApplicationIntent=ReadWrite;MultiSubnetFailover=False;MultipleActiveResultSets=true");

}

This project is outside the MVC project as a standalone ASP.NET Core 1.0 project. 该项目作为独立的ASP.NET Core 1.0项目位于MVC项目之外。 It also has a empty Program.cs file in it which seems to be required to execute the code-to-database command lines (dotnet ef migrations add and dotnet ef database update). 它还有一个空的Program.cs文件,它似乎是执行代码到数据库命令行所必需的(dotnet ef migrations add和dotnet ef database update)。

The reason we have a hard coded connection string in the DbConext is because when we use the following code, we get an object reference not set to an instance to an object exception, when executing the dotnet ef commands. 我们在DbConext中有一个硬编码连接字符串的原因是因为当我们使用下面的代码时,在执行dotnet ef命令时,我们得到一个对象引用未设置为对象异常的实例。

  protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder) {

    optionsBuilder.UseSqlServer(ConfigurationManager.ConnectionStrings["StandardDatabase"].ConnectionString);

  }

However, since we have a Program.cs, if we add a Debug.WriteLine for the connection string and run the project, it does return the correct connections string and if we set the connection string in the appsettings.json file in the UI, the UI will successfully connect as well. 但是,由于我们有一个Program.cs,如果我们为连接字符串添加Debug.WriteLine并运行项目,它会返回正确的连接字符串,如果我们在U​​I中的appsettings.json文件中设置连接字符串,用户界面也将成功连接。

THE ISSUE: The above mentioned stack is what we use for several "Micro Apps", which means we have several projects that connect to several databases. 问题:上面提到的堆栈是我们用于几个“Micro Apps”的东西,这意味着我们有几个连接到多个数据库的项目。 We also want to take advantage of Development, Staging and Production connection strings. 我们还希望利用Development,Staging和Production连接字符串。

If we use Configuration Manager Connection String, everything is good for daily operations; 如果我们使用Configuration Manager连接字符串,一切都适合日常操作; however, when ever we want to utilize Entity Frameworks code to database command lines, we need to go in to each repository we want to update and change the DbContext to a hard coded connection string, execute the commands, then change them back to when done, which becomes quite troublesome. 但是,当我们想要将Entity Frameworks代码用于数据库命令行时,我们需要进入我们想要更新的每个存储库,并将DbContext更改为硬编码连接字符串,执行命令,然后将它们更改回完成时,这变得非常麻烦。

THE QUESTION: Are we just doing this wrong, is there a preferred practice for setting up an Entity Framework Core 1.0 stack which allows us not to manually have to change the DbContext but take advantage of configuration files across the board? 问题:我们只是做错了吗?是否有一个首选实践来设置Entity Framework Core 1.0堆栈,它允许我们不必手动更改DbContext但是充分利用配置文件?

Any direction would be appreciated! 任何方向将不胜感激!

EF Core is intended to be configured via dependency injection. EF Core旨在通过依赖注入进行配置。 Dependency injection keeps your DbContext clean, and independent of implementation details of the environment. 依赖注入使您的DbContext保持干净,并且独立于环境的实现细节。

Your initial solution of hard-coding connection strings tightly coupled the DbContext to the knowledge of where the database is located. 您的硬编码连接字符串的初始解决方案将DbContext紧密耦合到数据库所在位置的知识。 That's obviously a problem. 这显然是一个问题。 But your proposed solution tightly couples the DbContext to the knowledge of a particular configuration file. 但是您提出的解决方案将DbContext与特定配置文件的知识紧密结合在一起。 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. 要使DbContext独立于环境细节,请创建一个构造函数,该构造函数接受DbContextOptions参数并调用基类构造函数。

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

Do this instead of overriding OnConfiguring . 这样做而不是覆盖OnConfiguring Then initialize it in the Startup.cs of your host application. 然后在主机应用程序的Startup.cs中初始化它。 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. 现在,您可以从任何地方使用您的DbContext。

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: 我按照Juunas的建议,在我的Repository DbContext类中添加了以下代码:

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. 这与dotnet ef命令行工具完美配合,而且我的MVC UI在我的startup.c中坚持使用以下默认代码的多环境设置也很好。

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. IDbContextFactory也可能有所帮助。 EF Command Line Tools and DI can use this factory to create instances of your DBContext. EF命令行工具和DI可以使用此工厂来创建DBContext的实例。 Design Time services (eg 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);
        }
    }
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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