How to pass connection string from appsettings.[name].json to DbContext in .NET Core?

痴心易碎 提交于 2019-12-24 01:46:19

问题


I have a .net core app. I write my connection string in appsettings.json file. But, now, I want to get that connection string for my context. How to do that?

In .net framework 4.6 I used this:

ConfigurationManager.ConnectionStrings["ConnStrName"].ConnectionString;

I have appsettings.Development.json like this (*** could be any name):

"ConnectionStrings": {
    "***": "Server=***;Database=****;Trusted_Connection=True;MultipleActiveResultSets=true;"
  }

I added service:

services.AddTransient<MyContext>(provider =>
            {
                return new MyContext(configuration["ConnectionStrings:***"]);
            });

and this is context constructor (ONLY THIS, not default ones because if I write a default one doesn't take my connection string from json file):

public MyContext(string connectionString)
        : base(connectionString)
    {
        try
        {
            this.Database.Log = (s) => System.Diagnostics.Debug.Write(s);
        }
        catch (Exception e)
        {
            //CurrentLogger.Log.Error(e);
        }
    }

After that I've got this error after I run Enable-Migration command

The target context 'MyContext' is not constructible. Add a default constructor or provide an implementation of IDbContextFactory.

If somehow I could get connection string from json here:

all will be good. But I want to do that with a single line in .NET CORE if it would be possible, like in .net framework: with this:

ConfigurationManager.ConnectionStrings["ConnStrName"].ConnectionString;

.net framework 4.6


回答1:


Everything in .NET Core is built around dependency injection instead of using static instances of things like ConfigurationManager.

You could do this in a couple different ways.

First would be registering your DbContext in Startup.cs ConfigureServices using something like this:

services.AddDbContext<MyContext>(context => context.UseSqlServer(Configuration.GetConnectionString("name")));

Then when your repository/service/whatever class needs to use the Context, it will be injected into the class using the constructor so you can use it.

public class SomeClass(MyContext context)
{

}

Or, if you don't want to do it that way, you can also inject 'IConfiguration' into the constructor of your DbContext and then do use the IConfiguration to get the connection string:

public class SomeClass(IConfiguration config)
{
    config.GetConnectionString("name")
}



回答2:


My original answer won't work for you situation because I was assuming you were porting to .NET Core instead of maintaining compatibility between full .NET Framework projects and the new .NET Core project.

I did something similar with legacy projects and ended up creating a class that acted as a store for the connection strings, and then it would get populated differently depending on the project that is using it is .NET Core or full .NET Framework.

For full .NET Framework projects, it would populate the connection strings from the ConfigurationManager.

For .NET Core projects, you'd read in the connection strings from your appsettings.json and then pass in the connection strings to that class in your Startup.

Then you would have to change your references to the ConfigurationManager in your DbContext to the new class you created to retrieve connection strings.

public class DatabaseConfiguration
{
    /// <summary>
    /// Database Connection Strings
    /// </summary>
    private static List<ConnectionStringSettings> _conStrings;
    public static List<ConnectionStringSettings> ConnectionStrings
    {
        get
        {
            //If it wasn't initialized manually, Initialize using the Configuration Manager. 
            if (_conStrings == null || !_conStrings.Any())
            {
                Initialize();
            }

            return _conStrings;
        }
    }

    /// <summary>
    /// Sets the connection strings from the Configuration Manager.
    /// </summary>
    public static void Initialize()
    {
        _conStrings = new List<ConnectionStringSettings>();
            foreach (ConnectionStringSettings connection in ConfigurationManager.ConnectionStrings)
            {
                _conStrings.Add(connection);
            }
    }

    /// <summary>
    /// Sets the connection strings manually. This is used when the project is a .NET Core app because it doesn't use the Configuration Manager, app.config, or web.config.
    /// </summary>
    public static void Initialize(List<ConnectionStringSettings>connectionStrings)
    {                
        _conStrings = connectionSttrings;
    }

/// <summary>
/// Gets the connection string for a database with the given name.
/// </summary>
/// <param name="name">DB Name</param>
/// <returns>Connection String</returns>
public static string GetConnectionString(string name)
{
    var matchingConnection = ConnectionStrings.Find(c => c.Name == name);
    return matchingConnection?.ConnectionString;
}

}


来源:https://stackoverflow.com/questions/50176564/how-to-pass-connection-string-from-appsettings-name-json-to-dbcontext-in-net

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