【问题标题】:.Net Core passing connection string to DBContext class.Net Core 将连接字符串传递给 DBContext 类
【发布时间】:2021-11-18 21:19:43
【问题描述】:

刚开始使用 .Net Core 并面临将连接字符串信息传递到上下文控制台项目。

我有 4 个项目,使用 .Net Core 创建。

  1. MVC
  2. 服务层
  3. 域层
  4. 数据层

在 MVC 项目中,我有 Startup.cs 文件,我正在读取 appsettings.json 文件

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

            services.AddMvc();

            // Add appsettings
            services.Configure<AppSettingsConfig>(Configuration.GetSection("AppSettings")); 
}


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

        if (env.IsDevelopment())
        {
            // This will push telemetry data through Application Insights pipeline faster, allowing you to view results immediately.
            builder.AddApplicationInsightsSettings(developerMode: true);
        }
        Configuration = builder.Build();
    }

在我的第 4 个项目(数据层)中,该控制台项目具有以下 DBContext 类。这个项目没有我 MVC 项目所拥有的 Startup.cs。 VS 2015 默认不创建。

public class MyDWContext : DbContext
{
    public MyDWContext() : base ()
    {

    }

    protected override void OnModelCreating(ModelBuilder modelBuilder)
    {
        base.OnModelCreating(modelBuilder);


    }

    protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
    {            
        optionsBuilder.UseSqlServer(@"Data Source=localhost;Initial Catalog=MyDW; Persist Security Info = False; User ID = TempUser; Password = Temp123");
    }

    public DbSet<User> Users { get; set; }
    public DbSet<Class> Classs { get; set; }
}

我也去过其他帖子,但我相信它是使用旧版本或 RC 版本创建的。所以有时我找不到正确的对象或 .Net 类。

由于我在 MVC 项目中有连接字符串,我如何在 MVC 调用数据层期间使用连接字符串。

我也有 Web.API(核心)项目,并且有自己的连接字符串(连接字符串中的不同用户配置,只有读取访问权限)。当我从 Web2.API 项目进行调用时,如何使用 Web2.API 连接字符串。

【问题讨论】:

    标签: asp.net-core


    【解决方案1】:

    不是将连接字符串传递给DbContext,而是在Startup.cs(如果可能)中配置DbContext 是更好的方法。请参阅官方docs 了解如何配置DbContext 并通过依赖注入使用它。

    编辑:下面的代码不是好方法

    但是,如果您想将连接字符串传递给DbContext,您可以使用options pattern

    这是一个如何使用选项模式传递连接字符串的示例:

    首先你需要一个可以从数据层和MVC层访问的选项类

    public class ConnectionStringOption
    {
         public string ConStr { get ; set; }
    }
    

    然后设置选项值

    public void ConfigureServices(IServiceCollection services)
    {
         services.AddOptions();
         services.Configure<ConnectionStringOption>(options=>
         {
             // set connection string from configuration  
             options.ConStr = Configuration.GetConnectionString("Default");
         });      
    }
    

    appsetting.json

    {
      "ConnectionStrings": {
        "Default": "<your connection string>"
      }
    }
    

    终于DbContext

        private readonly IOptions<ConnectionStringOption> _conStrOptions;
    
        protected YourDbContext()
        {
        }
        public YourDbContext(IOptions<ConnectionStringOption> conStrOptions, DbContextOptions options) 
            : base(options)
        {
            _conStrOptions= conStrOptions;
        }
    

    以其他方式编辑

    使用静态服务定位器可能是一个解决方案:

    在数据层中创建DependencyResolver

    public static class DependencyResolver
    {
        private static IServiceProvider _provider;
        public static IServiceProvider ServiceProvider
        {
            get
            {
                return _provider;
            }
            set
            {
                if(_provider == null)
                {
                    _provider = value;
                }
            }
        }
    }
    

    ConfigureServices方法中

        public void ConfigureServices(IServiceCollection services)
        {
            // other stuff
            services.AddOptions();
            services.Configure<ConnectionStringOption>(options=>
            {
                // set connection string from configuration  
                options.ConStr = Configuration.GetConnectionString("Default");
            }); 
            DependencyResolver.ServiceProvider = services.BuildServiceProvider();
        }
    

    最后得到选项:

    protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
    {            
        var conStr = DependencyResolver.ServiceLocator.GetService<IOptions<ConnectionStringOption>>().Value.ConStr;
        optionsBuilder.UseSqlServer();
    }
    

    对以前愚蠢方式的最终编辑

    public static class ConnectionStringGetter
    {
        public static string ConStr{get;set;}
    }
    
    public Startup(IHostingEnvironment env)
    {
        //...
        Configuration = builder.Build();
        ConnectionStringGetter.ConStr =  Configuration.GetConnectionString("Default");
    }
    
    protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
    {            
        optionsBuilder.UseSqlServer(ConnectionStringGetter.ConStr);
    }
    

    【讨论】:

    • 别介意第二种方式,它似乎不是有效的方式。
    • 感谢回复,但是我可以在数据层的 OnConfiguring 函数中使用 _conStrOptions 属性吗? protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder) {}
    • 可以,但是在这种情况下,您应该使用OnConfiguring 来配置DbContext,而您的DbContext 将取决于数据库(例如SqlServer)提供程序。我认为这不是一个好习惯。
    • _ConStrOptions 在后续调用期间为空。 optionsBuilder.UseSqlServer(_conStrOptions.Value.ConStr);
    • 您是否在Startup.cs 中配置了DbContext,例如:services.AddDbContext&lt;YourDbContextContext&gt;();
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2020-12-07
    • 2011-06-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多